| Remote Access Control |

# cmac.c

Go to the documentation of this file.

    00001 // This file has been prepared for Doxygen automatic documentation generation.
    00048 #include "cmac.h"
    00049 #include "aes.h"
    00050 #include "memory.h"
    00051 #include "common.h"
    00052 #include "config.h"
    00053
    00054
    00055
    00057 __no_init byte __eeprom CMACSubkey[ CMAC_SUBKEY_SIZE ];
    00058
    00059
    00060
    00061 void calcCMACSubkey( byte * cryptoBlock )
    00062 {
    00063         byte blockSize;
    00064         byte * blockPtr;
    00065         byte overflow;
    00066
    00067         // Fill crypto block with all zeros.
    00068         blockSize = BLOCK_SIZE;
    00069         blockPtr = cryptoBlock;
    00070         do {
    00071                 *blockPtr++ = 0;
    00072         } while( --blockSize );
    00073
    00074         // Encrypt zeros with secret key (assuming
    00075         // key schedule has been created with secret key)
    00076         cipherLookup( cryptoBlock );
    00077
    00078         // Multiply by 2 modulo (0b1^120 cat 0b10000111).
    00079         blockSize = BLOCK_SIZE - 1;
    00080         blockPtr = cryptoBlock;
    00081         overflow = blockPtr[0] & 0x80;
    00082         do {
    00083                 blockPtr[0] = (blockPtr[0] << 1) | (blockPtr[1] >> 7);
    00084                 ++blockPtr;
    00085         } while( --blockSize );
    00086         blockPtr[0] <<= 1;
    00087         if( overflow ) {
    00088                 blockPtr[0] ^= 0x87;
    00089         }
    00090
    00091 #if MESSAGE_SIZE_WO_MAC < BLOCK_SIZE
    00092         // Multiply by 2 modulo (0b1^120 cat 0b10000111) again.
    00093         blockSize = BLOCK_SIZE - 1;
    00094         blockPtr = cryptoBlock;
    00095         overflow = blockPtr[0] & 0x80;
    00096         do {
    00097                 blockPtr[0] = (blockPtr[0] << 1) | (blockPtr[1] >> 7);
    00098                 ++blockPtr;
    00099         } while( --blockSize );
    00100         blockPtr[0] <<= 1;
    00101         if( overflow ) {
    00102                 blockPtr[0] ^= 0x87;
    00103         }
    00104 #endif
    00105
    00106         copyBytesToEEPROM( CMACSubkey, cryptoBlock, BLOCK_SIZE );
    00107 }
    00108
    00109
    00110
    00111 void calcCMAC( const byte * message, byte * MACStorage )
    00112 {
    00113         // Copy message data to MACStorage, which should be BLOCK_SIZE.
    00114         copyBytes( MACStorage, message, MESSAGE_SIZE_WO_MAC );
    00115
    00116 #if MESSAGE_SIZE_WO_MAC < BLOCK_SIZE
    00117         // Pad message before calculating CMAC.
    00118   #if MESSAGE_SIZE_WO_MAC + 1 < BLOCK_SIZE
    00119         byte pos = MESSAGE_SIZE_WO_MAC + 1;
    00120         do {
    00121                 MACStorage[ pos ] = 0x00;
    00122         } while( ++pos < BLOCK_SIZE );
    00123   #endif
    00124         MACStorage[ MESSAGE_SIZE_WO_MAC ] = 0x80;
    00125 #endif
    00126
    00127         // Add (XOR) subkey.
    00128         addConstantFromEEPROM( MACStorage, CMACSubkey, BLOCK_SIZE );
    00129
    00130         // Encrypt, assuming secret key schedule is precalculated.
    00131         cipherLookup( MACStorage );
    00132 }
    00133

@DOC_TITLE@