📄 cmm_aes.c
字号:
if( KT_init ) { for( i = 0; i < 256; i++ ) { KT0[i] = RT0[ FSb[i] ]; KT1[i] = RT1[ FSb[i] ]; KT2[i] = RT2[ FSb[i] ]; KT3[i] = RT3[ FSb[i] ]; } KT_init = 0; } SK = (uint32 *) ctx->drk; *SK++ = *RK++; *SK++ = *RK++; *SK++ = *RK++; *SK++ = *RK++; for( i = 1; i < ctx->nr; i++ ) { RK -= 8; *SK++ = KT0[ (uint8) ( *RK >> 24 ) ] ^ KT1[ (uint8) ( *RK >> 16 ) ] ^ KT2[ (uint8) ( *RK >> 8 ) ] ^ KT3[ (uint8) ( *RK ) ]; RK++; *SK++ = KT0[ (uint8) ( *RK >> 24 ) ] ^ KT1[ (uint8) ( *RK >> 16 ) ] ^ KT2[ (uint8) ( *RK >> 8 ) ] ^ KT3[ (uint8) ( *RK ) ]; RK++; *SK++ = KT0[ (uint8) ( *RK >> 24 ) ] ^ KT1[ (uint8) ( *RK >> 16 ) ] ^ KT2[ (uint8) ( *RK >> 8 ) ] ^ KT3[ (uint8) ( *RK ) ]; RK++; *SK++ = KT0[ (uint8) ( *RK >> 24 ) ] ^ KT1[ (uint8) ( *RK >> 16 ) ] ^ KT2[ (uint8) ( *RK >> 8 ) ] ^ KT3[ (uint8) ( *RK ) ]; RK++; } RK -= 8; *SK++ = *RK++; *SK++ = *RK++; *SK++ = *RK++; *SK++ = *RK++; return( 0 );}/* AES 128-bit block encryption routine */void rt_aes_encrypt(aes_context *ctx, uint8 input[16], uint8 output[16] ){ uint32 *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3; RK = (uint32 *) ctx->erk; GET_UINT32( X0, input, 0 ); X0 ^= RK[0]; GET_UINT32( X1, input, 4 ); X1 ^= RK[1]; GET_UINT32( X2, input, 8 ); X2 ^= RK[2]; GET_UINT32( X3, input, 12 ); X3 ^= RK[3];#define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \{ \ RK += 4; \ \ X0 = RK[0] ^ FT0[ (uint8) ( Y0 >> 24 ) ] ^ \ FT1[ (uint8) ( Y1 >> 16 ) ] ^ \ FT2[ (uint8) ( Y2 >> 8 ) ] ^ \ FT3[ (uint8) ( Y3 ) ]; \ \ X1 = RK[1] ^ FT0[ (uint8) ( Y1 >> 24 ) ] ^ \ FT1[ (uint8) ( Y2 >> 16 ) ] ^ \ FT2[ (uint8) ( Y3 >> 8 ) ] ^ \ FT3[ (uint8) ( Y0 ) ]; \ \ X2 = RK[2] ^ FT0[ (uint8) ( Y2 >> 24 ) ] ^ \ FT1[ (uint8) ( Y3 >> 16 ) ] ^ \ FT2[ (uint8) ( Y0 >> 8 ) ] ^ \ FT3[ (uint8) ( Y1 ) ]; \ \ X3 = RK[3] ^ FT0[ (uint8) ( Y3 >> 24 ) ] ^ \ FT1[ (uint8) ( Y0 >> 16 ) ] ^ \ FT2[ (uint8) ( Y1 >> 8 ) ] ^ \ FT3[ (uint8) ( Y2 ) ]; \} AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 1 */ AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 2 */ AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 3 */ AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 4 */ AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 5 */ AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 6 */ AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 7 */ AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 8 */ AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 9 */ if( ctx->nr > 10 ) { AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 10 */ AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 11 */ } if( ctx->nr > 12 ) { AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 12 */ AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 13 */ } /* last round */ RK += 4; X0 = RK[0] ^ ( FSb[ (uint8) ( Y0 >> 24 ) ] << 24 ) ^ ( FSb[ (uint8) ( Y1 >> 16 ) ] << 16 ) ^ ( FSb[ (uint8) ( Y2 >> 8 ) ] << 8 ) ^ ( FSb[ (uint8) ( Y3 ) ] ); X1 = RK[1] ^ ( FSb[ (uint8) ( Y1 >> 24 ) ] << 24 ) ^ ( FSb[ (uint8) ( Y2 >> 16 ) ] << 16 ) ^ ( FSb[ (uint8) ( Y3 >> 8 ) ] << 8 ) ^ ( FSb[ (uint8) ( Y0 ) ] ); X2 = RK[2] ^ ( FSb[ (uint8) ( Y2 >> 24 ) ] << 24 ) ^ ( FSb[ (uint8) ( Y3 >> 16 ) ] << 16 ) ^ ( FSb[ (uint8) ( Y0 >> 8 ) ] << 8 ) ^ ( FSb[ (uint8) ( Y1 ) ] ); X3 = RK[3] ^ ( FSb[ (uint8) ( Y3 >> 24 ) ] << 24 ) ^ ( FSb[ (uint8) ( Y0 >> 16 ) ] << 16 ) ^ ( FSb[ (uint8) ( Y1 >> 8 ) ] << 8 ) ^ ( FSb[ (uint8) ( Y2 ) ] ); PUT_UINT32( X0, output, 0 ); PUT_UINT32( X1, output, 4 ); PUT_UINT32( X2, output, 8 ); PUT_UINT32( X3, output, 12 );}/* AES 128-bit block decryption routine */void rt_aes_decrypt( aes_context *ctx, uint8 input[16], uint8 output[16] ){ uint32 *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3; RK = (uint32 *) ctx->drk; GET_UINT32( X0, input, 0 ); X0 ^= RK[0]; GET_UINT32( X1, input, 4 ); X1 ^= RK[1]; GET_UINT32( X2, input, 8 ); X2 ^= RK[2]; GET_UINT32( X3, input, 12 ); X3 ^= RK[3];#define AES_RROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \{ \ RK += 4; \ \ X0 = RK[0] ^ RT0[ (uint8) ( Y0 >> 24 ) ] ^ \ RT1[ (uint8) ( Y3 >> 16 ) ] ^ \ RT2[ (uint8) ( Y2 >> 8 ) ] ^ \ RT3[ (uint8) ( Y1 ) ]; \ \ X1 = RK[1] ^ RT0[ (uint8) ( Y1 >> 24 ) ] ^ \ RT1[ (uint8) ( Y0 >> 16 ) ] ^ \ RT2[ (uint8) ( Y3 >> 8 ) ] ^ \ RT3[ (uint8) ( Y2 ) ]; \ \ X2 = RK[2] ^ RT0[ (uint8) ( Y2 >> 24 ) ] ^ \ RT1[ (uint8) ( Y1 >> 16 ) ] ^ \ RT2[ (uint8) ( Y0 >> 8 ) ] ^ \ RT3[ (uint8) ( Y3 ) ]; \ \ X3 = RK[3] ^ RT0[ (uint8) ( Y3 >> 24 ) ] ^ \ RT1[ (uint8) ( Y2 >> 16 ) ] ^ \ RT2[ (uint8) ( Y1 >> 8 ) ] ^ \ RT3[ (uint8) ( Y0 ) ]; \} AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 1 */ AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 2 */ AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 3 */ AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 4 */ AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 5 */ AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 6 */ AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 7 */ AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 8 */ AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 9 */ if( ctx->nr > 10 ) { AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 10 */ AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 11 */ } if( ctx->nr > 12 ) { AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 12 */ AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 13 */ } /* last round */ RK += 4; X0 = RK[0] ^ ( RSb[ (uint8) ( Y0 >> 24 ) ] << 24 ) ^ ( RSb[ (uint8) ( Y3 >> 16 ) ] << 16 ) ^ ( RSb[ (uint8) ( Y2 >> 8 ) ] << 8 ) ^ ( RSb[ (uint8) ( Y1 ) ] ); X1 = RK[1] ^ ( RSb[ (uint8) ( Y1 >> 24 ) ] << 24 ) ^ ( RSb[ (uint8) ( Y0 >> 16 ) ] << 16 ) ^ ( RSb[ (uint8) ( Y3 >> 8 ) ] << 8 ) ^ ( RSb[ (uint8) ( Y2 ) ] ); X2 = RK[2] ^ ( RSb[ (uint8) ( Y2 >> 24 ) ] << 24 ) ^ ( RSb[ (uint8) ( Y1 >> 16 ) ] << 16 ) ^ ( RSb[ (uint8) ( Y0 >> 8 ) ] << 8 ) ^ ( RSb[ (uint8) ( Y3 ) ] ); X3 = RK[3] ^ ( RSb[ (uint8) ( Y3 >> 24 ) ] << 24 ) ^ ( RSb[ (uint8) ( Y2 >> 16 ) ] << 16 ) ^ ( RSb[ (uint8) ( Y1 >> 8 ) ] << 8 ) ^ ( RSb[ (uint8) ( Y0 ) ] ); PUT_UINT32( X0, output, 0 ); PUT_UINT32( X1, output, 4 ); PUT_UINT32( X2, output, 8 ); PUT_UINT32( X3, output, 12 );}/* ========================================================================== Description: ENCRYPT AES GTK before sending in EAPOL frame. AES GTK length = 128 bit, so fix blocks for aes-key-wrap as 2 in this function. This function references to RFC 3394 for aes key wrap algorithm. Return: ==========================================================================*/ VOID AES_GTK_KEY_WRAP( IN UCHAR *key, IN UCHAR *plaintext, IN UINT32 p_len, OUT UCHAR *ciphertext){ UCHAR A[8], BIN[16], BOUT[16]; UCHAR R[512]; INT num_blocks = p_len/8; // unit:64bits INT i, j; aes_context aesctx; UCHAR xor; rt_aes_set_key(&aesctx, key, 128); // Init IA for (i = 0; i < 8; i++) A[i] = 0xa6; //Input plaintext for (i = 0; i < num_blocks; i++) { for (j = 0 ; j < 8; j++) R[8 * (i + 1) + j] = plaintext[8 * i + j]; } // Key Mix for (j = 0; j < 6; j++) { for(i = 1; i <= num_blocks; i++) { //phase 1 NdisMoveMemory(BIN, A, 8); NdisMoveMemory(&BIN[8], &R[8 * i], 8); rt_aes_encrypt(&aesctx, BIN, BOUT); NdisMoveMemory(A, &BOUT[0], 8); xor = num_blocks * j + i; A[7] = BOUT[7] ^ xor; NdisMoveMemory(&R[8 * i], &BOUT[8], 8); } } // Output ciphertext NdisMoveMemory(ciphertext, A, 8); for (i = 1; i <= num_blocks; i++) { for (j = 0 ; j < 8; j++) ciphertext[8 * i + j] = R[8 * i + j]; }}/* ======================================================================== Routine Description: Misc function to decrypt AES body Arguments: Return Value: Note: This function references to RFC 3394 for aes key unwrap algorithm. ========================================================================*/VOID AES_GTK_KEY_UNWRAP( IN UCHAR *key, OUT UCHAR *plaintext, IN UINT32 c_len, IN UCHAR *ciphertext) { UCHAR A[8], BIN[16], BOUT[16]; UCHAR xor; INT i, j; aes_context aesctx; UCHAR *R; INT num_blocks = c_len/8; // unit:64bits os_alloc_mem(NULL, (PUCHAR *)&R, 512); if (R == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("!!!AES_GTK_KEY_UNWRAP: no memory!!!\n")); return; } /* End of if */ // Initialize NdisMoveMemory(A, ciphertext, 8); //Input plaintext for(i = 0; i < (c_len-8); i++) { R[ i] = ciphertext[i + 8]; } rt_aes_set_key(&aesctx, key, 128); for(j = 5; j >= 0; j--) { for(i = (num_blocks-1); i > 0; i--) { xor = (num_blocks -1 )* j + i; NdisMoveMemory(BIN, A, 8); BIN[7] = A[7] ^ xor; NdisMoveMemory(&BIN[8], &R[(i-1)*8], 8); rt_aes_decrypt(&aesctx, BIN, BOUT); NdisMoveMemory(A, &BOUT[0], 8); NdisMoveMemory(&R[(i-1)*8], &BOUT[8], 8); } } // OUTPUT for(i = 0; i < c_len; i++) { plaintext[i] = R[i]; } os_free_mem(NULL, R);}/* ======= The related function of AES-128-CMAC ======= */VOID leftshift_onebit( IN PUCHAR input, OUT PUCHAR output){ INT i; UCHAR overflow = 0; for (i=15; i>=0; i--) { output[i] = input[i] << 1; output[i] |= overflow; overflow = (input[i] & 0x80) ? 1 : 0; } }VOID do_padding( IN PUCHAR lastb, OUT PUCHAR pad, IN INT len){ INT j; for (j=0; j<16; j++) { if (j < len) pad[j] = lastb[j]; else if (j == len) pad[j] = 0x80; else pad[j] = 0x00; }}/* * The Subkey Generation Algorithm */VOID generate_subkey( IN PUCHAR key, OUT PUCHAR K1, OUT PUCHAR K2){ aes_context aesctx; UCHAR aes_128_key[16]; UCHAR const_Zero[16]; UCHAR tmp[16]; UCHAR const_Rb[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87}; // initial the key material memset(const_Zero, 0, 16); memset(aes_128_key, 0, 16); // AES-128 with key is applied to an all-zero input block rt_aes_set_key(&aesctx, key, 128); rt_aes_encrypt(&aesctx, const_Zero, aes_128_key); // derive K1(128-bit first subkey) and K2(128-bit second subkey), refer to rfc-4493 ch 2.3 if ((aes_128_key[0] & 0x80) == 0) { leftshift_onebit(aes_128_key, K1); } else { leftshift_onebit(aes_128_key, tmp); xor_128(tmp, const_Rb, K1); } if ((K1[0] & 0x80) == 0) { leftshift_onebit(K1, K2); } else { leftshift_onebit(K1, tmp); xor_128(tmp, const_Rb, K2); } }/* * AES-CMAC Algorithm. (refer to rfc-4493 and SP800-38B) * * Input : key (128-bit key) * input (message to be authenticated) * len (length of the message in octets) * * output: mac (message authentication code) */VOID AES_128_CMAC( IN PUCHAR key, IN PUCHAR input, IN INT len, OUT PUCHAR mac){ UCHAR X[16], Y[16], M_last[16], padded[16]; UCHAR K1[16], K2[16]; aes_context aesctx; INT n, i, flag; generate_subkey(key, K1, K2); n = (len+15) / 16; // n is number of rounds if (n == 0) { n = 1; flag = 0; } else { if ((len%16) == 0) flag = 1; // indicate that last block is a complete block else flag = 0; // indicate that last block is not a complete block } if (flag) { xor_128(&input[16*(n-1)], K1, M_last); } else { do_padding(&input[16*(n-1)], padded, len%16); xor_128(padded, K2, M_last); } memset(X, 0, 16); for (i=0; i<n-1; i++) { xor_128(X, &input[16*i], Y); rt_aes_set_key(&aesctx, key, 128); rt_aes_encrypt(&aesctx, Y, X); } xor_128(X, M_last, Y); rt_aes_set_key(&aesctx, key, 128); rt_aes_encrypt(&aesctx, Y, X); for (i=0; i<16; i++) { mac[i] = X[i]; }}/* ======= The related function of AES-128-CMAC ======= */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -