cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

ecc.c (3038B)


      1/*
      2 * Calculate Error-correcting Codes. Used by NAND Flash controllers
      3 * (not by NAND chips).
      4 *
      5 * Copyright (c) 2006 Openedhand Ltd.
      6 * Written by Andrzej Zaborowski <balrog@zabor.org>
      7 *
      8 * This code is licensed under the GNU GPL v2.
      9 *
     10 * Contributions after 2012-01-13 are licensed under the terms of the
     11 * GNU GPL, version 2 or (at your option) any later version.
     12 */
     13
     14#include "qemu/osdep.h"
     15#include "migration/vmstate.h"
     16#include "hw/block/flash.h"
     17
     18/*
     19 * Pre-calculated 256-way 1 byte column parity.  Table borrowed from Linux.
     20 */
     21static const uint8_t nand_ecc_precalc_table[] = {
     22    0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a,
     23    0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00,
     24    0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f,
     25    0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65,
     26    0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c,
     27    0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66,
     28    0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59,
     29    0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03,
     30    0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33,
     31    0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69,
     32    0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56,
     33    0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c,
     34    0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55,
     35    0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f,
     36    0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30,
     37    0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a,
     38    0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30,
     39    0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a,
     40    0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55,
     41    0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f,
     42    0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56,
     43    0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c,
     44    0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33,
     45    0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69,
     46    0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59,
     47    0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03,
     48    0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c,
     49    0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66,
     50    0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f,
     51    0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65,
     52    0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a,
     53    0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00,
     54};
     55
     56/* Update ECC parity count.  */
     57uint8_t ecc_digest(ECCState *s, uint8_t sample)
     58{
     59    uint8_t idx = nand_ecc_precalc_table[sample];
     60
     61    s->cp ^= idx & 0x3f;
     62    if (idx & 0x40) {
     63        s->lp[0] ^= ~s->count;
     64        s->lp[1] ^= s->count;
     65    }
     66    s->count ++;
     67
     68    return sample;
     69}
     70
     71/* Reinitialise the counters.  */
     72void ecc_reset(ECCState *s)
     73{
     74    s->lp[0] = 0x0000;
     75    s->lp[1] = 0x0000;
     76    s->cp = 0x00;
     77    s->count = 0;
     78}
     79
     80/* Save/restore */
     81const VMStateDescription vmstate_ecc_state = {
     82    .name = "ecc-state",
     83    .version_id = 0,
     84    .minimum_version_id = 0,
     85    .fields = (VMStateField[]) {
     86        VMSTATE_UINT8(cp, ECCState),
     87        VMSTATE_UINT16_ARRAY(lp, ECCState, 2),
     88        VMSTATE_UINT16(count, ECCState),
     89        VMSTATE_END_OF_LIST(),
     90    },
     91};