| 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
    00056 void calcCMACSubkey( byte * subKeyStorage,
    00057                 byte * scheduleBuffer,
    00058                 const byte * key )
    00059 {
    00060         byte blockSize;
    00061         byte * blockPtr;
    00062         bool overflow;
    00063
    00064         // Fill crypto block with all zeros.
    00065         blockSize = BLOCK_SIZE;
    00066         blockPtr = subKeyStorage;
    00067         do {
    00068                 *blockPtr++ = 0;
    00069         } while( --blockSize );
    00070
    00071         // Encrypt zeros with secret key.
    00072         cipher( subKeyStorage, scheduleBuffer, key );
    00073
    00074         // Multiply by 2 modulo (0b1^120 cat 0b10000111).
    00075         blockSize = BLOCK_SIZE - 1;
    00076         blockPtr = subKeyStorage;
    00077         overflow = blockPtr[0] & 0x80;
    00078         do {
    00079                 blockPtr[0] = (blockPtr[0] << 1) | (blockPtr[1] >> 7);
    00080                 ++blockPtr;
    00081         } while( --blockSize );
    00082         blockPtr[0] <<= 1;
    00083         if( overflow ) {
    00084                 blockPtr[0] ^= 0x87;
    00085         }
    00086
    00087 #if MESSAGE_SIZE_WO_MAC < BLOCK_SIZE
    00088         // Multiply by 2 modulo (0b1^120 cat 0b10000111) again.
    00089         blockSize = BLOCK_SIZE - 1;
    00090         blockPtr = subKeyStorage;
    00091         overflow = blockPtr[0] & 0x80;
    00092         do {
    00093                 blockPtr[0] = (blockPtr[0] << 1) | (blockPtr[1] >> 7);
    00094                 ++blockPtr;
    00095         } while( --blockSize );
    00096         blockPtr[0] <<= 1;
    00097         if( overflow ) {
    00098                 blockPtr[0] ^= 0x87;
    00099         }
    00100 #endif
    00101 }
    00102
    00103
    00104
    00105 void calcCMAC( const byte * message,
    00106                 const byte * CMACSubkey,
    00107                 byte * scheduleBuffer,
    00108                 const byte * key,
    00109                 byte * MACStorage )
    00110 {
    00111         // Copy message data to MACStorage, which should be BLOCK_SIZE.
    00112         copyBytes( MACStorage, message, MESSAGE_SIZE_WO_MAC );
    00113
    00114 #if MESSAGE_SIZE_WO_MAC < BLOCK_SIZE
    00115         // Pad message before calculating CMAC.
    00116   #if MESSAGE_SIZE_WO_MAC + 1 < BLOCK_SIZE
    00117         byte pos = MESSAGE_SIZE_WO_MAC + 1;
    00118         do {
    00119                 MACStorage[ pos ] = 0x00;
    00120         } while( ++pos < BLOCK_SIZE );
    00121   #endif
    00122         MACStorage[ MESSAGE_SIZE_WO_MAC ] = 0x80;
    00123 #endif
    00124
    00125         // Add (XOR) subkey.
    00126         addConstant( MACStorage, CMACSubkey, BLOCK_SIZE );
    00127
    00128         // Encrypt.
    00129         cipher( MACStorage, scheduleBuffer, key );
    00130 }
    00131

@DOC_TITLE@