/*****************************************************************************/ /* Rijndael encryption module */ /*****************************************************************************/ /* History of Change : */ /* 15 Oct 2002 pt: Beta release */ /* 23 Apr 2007 dag: brought over from Redirector 3.x */ /* In redirector 3.x it was in user mode space, */ /* but here it is kernel mode space. */ /*****************************************************************************/ #include "pch.h" #ifdef SCPR #ifdef DEBUG // define debug to get regular print outs of intermediate values void print_a(cr_blockMultiDim a); #endif #ifdef KAT_MCT // Test mode specified by NIST. See documentation #define rijndaelEncrypt(a,b,c) rijndaelEncryptRound(a,b,c,a->rounds) #define rijndaelDecrypt(a,b,c) rijndaelDecryptRound(a,b,c,0) #else static void rijndaelEncrypt ( cr_keyStruct *keyStr, cr_block in, cr_block out); static void rijndaelDecrypt ( cr_keyStruct *keyStr, cr_block in, cr_block out); #endif #define MODPOLY 0x1B // Modulo polynomial: x^4 + x^3 + x + 1 #if BLOCKCOLUMNS!=4 // When BLOCKCOLUMNS = 4, these values are hardcoded in the SW. static BYTE shifts[3][4][2] = { {{0, 0}, {1, 3}, {2, 2}, {3, 1}}, {{0, 0}, {1, 5}, {2, 4}, {3, 3}}, {{0, 0}, {1, 7}, {3, 5}, {4, 4}} }; #endif static BYTE S[256], Sinv[256]; // Substitute tables. Will be generated in Cipher_Init //#define xtime(x) ((BYTE)(((x)&0x80)?((x)<<1)^MODPOLY:((x)<<1))) // *x modulo x^4 + x^3 + x + 1 #define xtime(x) (j = (x), (BYTE)(((j)&0x80)?(j<<1)^MODPOLY:(j<<1))) // *x modulo x^4 + x^3 + x + 1 //#define xtime(x) ((BYTE)(((x)<<1)^(MODPOLY*((x)&0x80)))) // *x modulo x^4 + x^3 + x + 1 // Affine transformation f(j) #define fwd_affine(x) \ (j = (WORD)x, j ^= (j<<1)^(j<<2)^(j<<3)^(j<<4), 0x63^(BYTE)(j^(j>>8))) // Inverse affine transformation f^-1(j) #define inv_affine(x) \ (j = (WORD)x, j = (j<<1)^(j<<3)^(j<<6), 0x05^(BYTE)(j^(j>>8))) void aes_cipher_init( void ) { WORD j, i; BYTE k; /* Generate the S and Sinv substitute box tables instead of using const data. * * This will cost code, but overall will save ROM space. * * To save on RAM space needed for intermediate tables the values will be generated * * in a few steps * * Sinv[]: Alog(a) => => g(f^-1(a)) => * * S[]: Log(a) => g(a) => => f(g(a)) */ /* Generate Alog(a) in Sinv[] and Log(a) in S[] */ i = 0; k= 1; do { Sinv[i] = (BYTE)k; S[k] = (BYTE)i++; k ^= xtime(k); #ifdef DEBUG_TABLEGEN KdPrint(("i: %d, k: %d\r\n", i, k)); #endif } while (k != 1); S[0] = 0; Sinv[255] = 1; /* Convert Log(a), ie S[], into g(a). g(a): a -> a^-1 */ for (i=1;i<256;i++) { #ifdef DEBUG_TABLEGEN KdPrint(("S[%d]: %d, Sinv[%d]: %d\r\n", i, S[i], i, Sinv[i])); #endif S[i] = Sinv[255-S[i]]; } /* Generate g(f^-1(a)) into Sinv[], for a definition of f^-1 see [?] */ for (i=0;i<256;i++) { Sinv[i] = S[inv_affine(i)]; #ifdef DEBUG_TABLEGEN KdPrint(("S[%d]: %d, Sinv[%d]: %d\r\n", i, S[i], i, Sinv[i])); #endif } /* Generate f(g(a)) into S[], for a definition of f see [?] */ for (i=0;i<256;i++) { S[i] = fwd_affine(S[i]); #ifdef DEBUG_TABLEGEN KdPrint(("S[%d]: %d, Sinv[%d]: %d\r\n", i, S[i], i, Sinv[i])); #endif } } /********************************************************************************************/ /* Input: */ /* keyStr: pointer to an externally declared cr_keyStruct. */ /* key: pointer to an array of BYTEs holding the initial key. */ /* keyLen: length of key in bits. */ /* Ouput: */ /* *keyStr: cr_keyStruct filled with the round keys and possibly the key and block lengths.*/ /********************************************************************************************/ void aes_key_init( cr_keyStruct *keyStr, BYTE *key, int keyLen) { WORD j, i; WORD t; BYTE keyColumns, rounds; BYTE rcon; BYTE tk[MAXKEYCOLUMNS][4], *ubp1; DWORD *ubp2; //KdPrint(("Key prep\r\n")); keyColumns = (keyStr->keyColumns) = (BYTE)(keyLen>>5); //KdPrint(("KeyLength: %d\r\n", keyLen)); //KdPrint(("KeyColumns: %d\r\n", keyColumns)); /* Calculate the necessary round keys * The number of calculations depends on key length and block length */ rounds = (keyStr->rounds) = (keyColumns >= BLOCKCOLUMNS ? keyColumns : BLOCKCOLUMNS) + 6; memcpy(tk, key, keyColumns<<2); //KdPrint(("KeyRounds: %d\r\n", rounds)); #ifdef DEBUG_KEYS2 for(j = 0; j < keyColumns; j++) { for (i=0;i<4;i++) { KdPrint(("Key[%d][%d]: %2x\r\n", i, j, *(BYTE *)key++)); } } #endif memcpy(keyStr->roundKeys, tk, keyColumns<<2); t= keyColumns; rcon=1; while (t < (rounds+1)*BLOCKCOLUMNS) { /* while not enough round key material calculated */ /* calculate new values */ for(i = 0; i < 4; i++) tk[0][i] ^= S[tk[keyColumns-1][(i+1)&3]]; tk[0][0] ^= rcon; rcon = xtime(rcon); if (keyColumns != 8) for(j = 1; j < keyColumns; j++) *(DWORD *)tk[j] ^= *(DWORD *)tk[j-1]; else { for(j = 1; j < keyColumns/2; j++) *(DWORD *)tk[j] ^= *(DWORD *)tk[j-1]; for(i = 0; i < 4; i++) tk[j][i] ^= S[tk[j - 1][i]]; for(j = keyColumns/2 + 1; j < keyColumns; j++) *(DWORD *)tk[j] ^= *(DWORD *)tk[j-1]; } /* copy values into round key array */ for(j = 0; (j < keyColumns) && (t < (rounds+1)*BLOCKCOLUMNS); j++, t++) { ((DWORD *)keyStr->roundKeys)[t] = *(DWORD *)tk[j]; } } } #ifdef ENCRYPT_MODE_ECB /********************************************************************************************/ /* Input: */ /* keyStr: pointer to an externally declared cr_keyStruct. */ /* plainText: pointer to an array of cr_blocks holding the plain text. */ /* nBlocks: number of cr_blocks in the plainText and cipherText arrays. */ /* cipherText: pointer to an array of cr_blocks that will be holding the encrypted text. */ /* Ouput: */ /* *cipherText: array filled with the encrypted text. */ /********************************************************************************************/ void aes_block_encrypt_ECB(cr_keyStruct *keyStr, cr_block *plainText, int nBlocks, cr_block *cipherText) { for (;nBlocks--;cipherText++, plainText++) { rijndaelEncrypt (keyStr, plainText[0], cipherText[0]); /* Encrypt */ } } /********************************************************************************************/ /* Input: */ /* keyStr: pointer to an externally declared cr_keyStruct. */ /* cipherText: pointer to an array of cr_blocks holding the encrypted text. */ /* nBlocks: number of cr_blocks in the plainText and cipherText arrays. */ /* cipherText: pointer to an array of cr_blocks that will be holding the plain text. */ /* Ouput: */ /* *plainText: array filled with the encrypted text. */ /********************************************************************************************/ void aes_block_decrypt_ECB(cr_keyStruct *keyStr, cr_block *cipherText, int nBlocks, cr_block *plainText) { for (;nBlocks--;cipherText++, plainText++) { rijndaelDecrypt (keyStr, cipherText[0], plainText[0]); } } #endif #ifdef ENCRYPT_MODE_CBC void aes_block_encrypt_CBC(cr_keyStruct *keyStr, cr_block initVec, cr_block *plainText, int nBlocks, cr_block *cipherText) { #if BLOCKCOLUMNS == 4 for (;nBlocks--;cipherText++,plainText++) { // KdPrint(("\r\nnBlocks %d\r\n", nBlocks)); // for (i=0;i<16;i++) KdPrint(("%c ",plainText[0][i])); // KdPrint(("ciphertext %x, prevblockptr %x, plaintext %x\r\n", cipherText, prevBlockPtr, plainText)); ((DWORD *)plainText)[0] ^= ((DWORD *)initVec)[0]; ((DWORD *)plainText)[1] ^= ((DWORD *)initVec)[1]; ((DWORD *)plainText)[2] ^= ((DWORD *)initVec)[2]; ((DWORD *)plainText)[3] ^= ((DWORD *)initVec)[3]; rijndaelEncrypt (keyStr, plainText[0], cipherText[0]); memcpy(initVec, cipherText, BLOCKSIZE); } #else DWORD *prevBlockPtr; BYTE i; prevBlockPtr = (DWORD *)initVec; for (;nBlocks--;) { // KdPrint(("\r\nnBlocks %d\r\n", nBlocks)); // for (i=0;i<16;i++) KdPrint(("%c ",plainText[0][i])); // KdPrint(("ciphertext %x, prevblockptr %x, plaintext %x\r\n", cipherText, prevBlockPtr, plainText)); for (i=BLOCKCOLUMNS;i>0;i--) { *((DWORD *)plainText)++ ^= *prevBlockPtr++; /* Exor one block of temp with input */ } rijndaelEncrypt (keyStr, plainText[-1], cipherText[0]); prevBlockPtr = ((DWORD *)cipherText); cipherText++; } // Copy last cipherText block to InitVec to chain to a next call to encrypt CBC memcpy(initVec, prevBlockPtr, BLOCKSIZE); #endif } /* Messes up *input. */ void aes_block_decrypt_CBC(cr_keyStruct *keyStr, cr_block initVec, cr_block *cipherText, int nBlocks, cr_block *plainText) { #if BLOCKCOLUMNS == 4 for (;nBlocks--;cipherText++,plainText++) { // KdPrint(("\r\nnBlocks %d\r\n", nBlocks)); // for (i=0;i<16;i++) KdPrint(("%2x ",cipherText[0][i])); rijndaelDecrypt (keyStr, cipherText[0], plainText[0]); ((DWORD *)plainText)[0] ^= ((DWORD *)initVec)[0]; ((DWORD *)plainText)[1] ^= ((DWORD *)initVec)[1]; ((DWORD *)plainText)[2] ^= ((DWORD *)initVec)[2]; ((DWORD *)plainText)[3] ^= ((DWORD *)initVec)[3]; memcpy(initVec, cipherText, BLOCKSIZE); } #else DWORD *prevBlockPtr; WORD i; for (;nBlocks--;cipherText++,plainText++) { // KdPrint(("\r\nnBlocks %d\r\n", nBlocks)); // for (i=0;i<16;i++) KdPrint(("%2x ",cipherText[0][i])); rijndaelDecrypt (keyStr, cipherText[0], plainText[0]); prevBlockPtr = (DWORD *)initVec; for (i=BLOCKCOLUMNS;i>0;i--) { *((DWORD *)plainText)++ ^= *prevBlockPtr++; /* Exor one block of temp with plaintext */ } memcpy(initVec, cipherText, BLOCKSIZE); } #endif } #endif // input output might be switched for decryption as used by Cobox SW. void aes_byte_encrypt(cr_keyStruct *keyStr, cr_block initVec, BYTE *input, int nBytes, BYTE *output, BYTE *left, enum cr_mode mode) { // register BYTE cx; BYTE *bx; BYTE more = *left; BYTE _CL; while (nBytes) { if (more==0) { //KdPrint(("aes_byte_encrypt calling rijndaelEncrypt\n")); rijndaelEncrypt (keyStr, initVec, initVec); more=BLOCKSIZE; } bx = (BYTE *)initVec + BLOCKSIZE - more; _CL = (nBytes keyStr->rounds) rds = keyStr->rounds; #endif #ifdef DEBUG_KEYS2 for (t=0;t<(keyStr->rounds+1)*BLOCKCOLUMNS;) for(j = 0; (j < 4) && (t < (keyStr->rounds+1)*BLOCKCOLUMNS); j++, t++) for(i = 0; i < 4; i++) { KdPrint(("roundKey [%d][%d][%d]: %2x\r\n", t / BLOCKCOLUMNS, i, t % BLOCKCOLUMNS, (keyStr->roundKeys)[t / BLOCKCOLUMNS][t % BLOCKCOLUMNS][i])); } KdPrint(("in:")); for (i = 0; i < 16; i++) KdPrint(("%2x ", in[i])); KdPrint(("\n")); #endif /* begin with a key addition */ #ifdef DEBUG_ENC KdPrint(("Encryption input\r\n")); print_a((cr_blockMultiDim *)in); //getch(); #endif c = in; (DWORD *)_SI = (DWORD *)out; rk = (DWORD *)(keyStr->roundKeys); #if BLOCKCOLUMNS == 4 ((DWORD *)_SI)[0] = ((DWORD *)c)[0] ^ rk[0]; ((DWORD *)_SI)[1] = ((DWORD *)c)[1] ^ rk[1]; ((DWORD *)_SI)[2] = ((DWORD *)c)[2] ^ rk[2]; ((DWORD *)_SI)[3] = ((DWORD *)c)[3] ^ rk[3]; rk +=BLOCKCOLUMNS; #else for(j = BLOCKCOLUMNS; j >0; j--) *((DWORD *)c)++ = *((DWORD *)_SI)++ ^ *rk++; #endif #ifdef DEBUG_ENC KdPrint(("Key Addition\r\n")); print_a((cr_blockMultiDim *)out); #endif #ifdef KAT_MCT for(r = 1; (r <= rds) && (r <= keyStr->rounds); r++) { #else r = keyStr->rounds; do { r--; #endif #ifdef DEBUG_ENC KdPrint(("\r\nRound: %d\r\n\r\n", r)); #endif #if BLOCKCOLUMNS == 4 /* i = 0 => shift = 0 */ out[0] = S[out[0]]; out[4] = S[out[4]]; out[8] = S[out[8]]; out[12] = S[out[12]]; /* i = 1 => shift = 1 */ j = S[out[1]]; out[1] = S[out[5]]; out[5] = S[out[9]]; out[9] = S[out[13]]; out[13] = j; /* i = 2 => shift = 2 */ j = S[out[2]]; out[2] = S[out[10]]; out[10] = j; j = S[out[6]]; out[6] = S[out[14]]; out[14] = j; /* i = 3 => shift = 3 */ j = S[out[3]]; out[3] = S[out[15]]; out[15] = S[out[11]]; out[11] = S[out[7]]; out[7] = j; #else /* Need to check this (BYTE *)_SI = out; for(j = BLOCKSIZE; j >0; j--) *((BYTE *)_SI)++ = S[*(BYTE *)_SI] ; (BYTE *)_SI = out; for (i=1;i<4;i++) { s = shifts[(BLOCKCOLUMNS - 4) >> 1][i][0]; for(j = 0; j < BLOCKCOLUMNS; j++) { ((BYTE *)_SI)[j] = ((BYTE *)_SI)[(j + s) % BLOCKCOLUMNS]; } ((BYTE *)_SI) += BLOCKCOLUMNS; } */ #endif #ifdef DEBUG_ENC KdPrint(("Substitute + Shift\r\n")); print_a((cr_blockMultiDim *)out); #endif if(r) { (BYTE *)_SI = out; for(k = 0; k < BLOCKCOLUMNS; k++) { u=((BYTE *)_SI)[0]; t=u ^ ((BYTE *)_SI)[1] ^ ((BYTE *)_SI)[2] ^ ((BYTE *)_SI)[3]; ((BYTE *)_SI)[0] ^= xtime(((BYTE *)_SI)[0] ^ ((BYTE *)_SI)[1]) ^ t; ((BYTE *)_SI)[1] ^= xtime(((BYTE *)_SI)[1] ^ ((BYTE *)_SI)[2]) ^ t; ((BYTE *)_SI)[2] ^= xtime(((BYTE *)_SI)[2] ^ ((BYTE *)_SI)[3]) ^ t; ((BYTE *)_SI)[3] ^= xtime(((BYTE *)_SI)[3] ^ u) ^ t; ((DWORD *)_SI)++; } } #ifdef DEBUG_ENC KdPrint(("Mix Columns\r\n")); print_a((cr_blockMultiDim *)out); #endif (DWORD *)_SI = (DWORD *)out; #if BLOCKCOLUMNS == 4 ((DWORD *)_SI)[0] ^= rk[0]; ((DWORD *)_SI)[1] ^= rk[1]; ((DWORD *)_SI)[2] ^= rk[2]; ((DWORD *)_SI)[3] ^= rk[3]; rk +=BLOCKCOLUMNS; #else for(j = BLOCKCOLUMNS; j >0; j--) *((DWORD *)_SI)++ ^= *rk++; #endif #ifdef DEBUG_ENC KdPrint(("Key Addition\r\n")); print_a((cr_blockMultiDim *)out); //getch(); #endif } while (r); #ifdef DEBUG_KEYS2 KdPrint(("out:")); for (i = 0; i < 16; i++) KdPrint(("%2x ", out[i])); KdPrint(("\n")); #endif } #ifdef KAT_MCT void rijndaelDecryptRound ( cr_keyStruct *keyStr, BYTE *a, int rds) #else static void rijndaelDecrypt ( cr_keyStruct *keyStr, cr_block in, cr_block out) #endif { register BYTE j; BYTE k, r, xe, xo, t, t2; DWORD *rk; BYTE *_SI; /* To decrypt: apply the inverse operations of the encrypt routine, * in opposite order * * (KeyAddition is an involution: it 's equal to its inverse) * (the inverse of Substitution with table S is Substitution with the inverse table of S) * (the inverse of Shiftrow is Shiftrow over a suitable distance) */ #ifdef KAT_MCT if (rds > keyStr->rounds) rds = keyStr->rounds; #endif rk = (DWORD *)(keyStr->roundKeys[keyStr->rounds][0]); #ifdef DEBUG_DEC KdPrint(("Decryption input\r\n")); print_a((cr_blockMultiDim *)in); #endif memcpy(out,in,BLOCKCOLUMNS<<2); #ifdef DEBUG_DEC KdPrint(("Copy Input\r\n")); print_a((cr_blockMultiDim *)out); #endif #ifdef KAT_MCT for(r = keyStr->rounds; r > rds; r--) #else for(r = keyStr->rounds; r > 0; r--) #endif { #if BLOCKCOLUMNS == 4 (DWORD *)_SI = (DWORD *)out; ((DWORD *)_SI)[0] ^= rk[0]; ((DWORD *)_SI)[1] ^= rk[1]; ((DWORD *)_SI)[2] ^= rk[2]; ((DWORD *)_SI)[3] ^= rk[3]; rk -=BLOCKCOLUMNS; #else (DWORD *)_SI = (DWORD *)&(out[BLOCKSIZE-BLOCKCOLUMNS]); for(j = BLOCKCOLUMNS; j >0; j--) *((DWORD *)_SI)-- ^= *rk--; #endif #ifdef DEBUG_DEC KdPrint(("\r\nRound: %d\r\n\n", r)); KdPrint(("Key Addition\r\n")); print_a((cr_blockMultiDim *)out); #endif if(r != keyStr->rounds) { (BYTE *)_SI = out; for(k = 0; k < BLOCKCOLUMNS; k++) { t=((BYTE *)_SI)[0] ^ ((BYTE *)_SI)[1] ^ ((BYTE *)_SI)[2] ^ ((BYTE *)_SI)[3]; xe = xtime(((BYTE *)_SI)[0] ^ ((BYTE *)_SI)[2]); xo = xtime(((BYTE *)_SI)[1] ^ ((BYTE *)_SI)[3]); t2 = xtime(xtime(xo ^ xe)) ^ t; ((BYTE *)_SI)[0] ^= xtime(((BYTE *)_SI)[0] ^ ((BYTE *)_SI)[1] ^ xe) ^ t2; ((BYTE *)_SI)[1] ^= xtime(((BYTE *)_SI)[1] ^ ((BYTE *)_SI)[2] ^ xo) ^ t2; ((BYTE *)_SI)[2] ^= xtime(((BYTE *)_SI)[2] ^ ((BYTE *)_SI)[3] ^ xe) ^ t2; ((BYTE *)_SI)[3] = ((BYTE *)_SI)[0] ^ ((BYTE *)_SI)[1] ^ ((BYTE *)_SI)[2] ^ t; ((DWORD *)_SI)++; } #ifdef DEBUG_DEC KdPrint(("Inverse Mix Columns\r\n")); print_a((cr_blockMultiDim *)out); #endif } #if BLOCKCOLUMNS == 4 /* i = 0 => shift = 0 */ out[0] = Sinv[out[0]]; out[4] = Sinv[out[4]]; out[8] = Sinv[out[8]]; out[12] = Sinv[out[12]]; /* i = 1 => shift = 3 */ j = Sinv[out[1]]; out[1] = Sinv[out[13]]; out[13] = Sinv[out[9]]; out[9] = Sinv[out[5]]; out[5] = j; /* i = 2 => shift = 2 */ j = Sinv[out[2]]; out[2] = Sinv[out[10]]; out[10] = j; j = Sinv[out[6]]; out[6] = Sinv[out[14]]; out[14] = j; /* i = 3 => shift = 1 */ j = Sinv[out[3]]; out[3] = Sinv[out[7]]; out[7] = Sinv[out[11]]; out[11] = Sinv[out[15]]; out[15] = j; #else /* need to check this ((BYTE *)_SI) = out; for (i=1;i<4;i++) { s = shifts[(BLOCKCOLUMNS - 4) >> 1][i][0]; for(j = 0; j < BLOCKCOLUMNS; j++) { ((BYTE *)_SI)[j] = ((BYTE *)_SI)[(j + s) % BLOCKCOLUMNS]; } ((BYTE *)_SI) += BLOCKCOLUMNS; } */ #endif #ifdef DEBUG_DEC KdPrint(("Inverse Substitute + Shift Rows\r\n")); print_a((cr_blockMultiDim *)out); #endif } #ifdef KAT_MCT if (rds == 0) #endif { /* End with the extra key addition */ #if BLOCKCOLUMNS == 4 (DWORD *)_SI = (DWORD *)out; ((DWORD *)_SI)[0] ^= rk[0]; ((DWORD *)_SI)[1] ^= rk[1]; ((DWORD *)_SI)[2] ^= rk[2]; ((DWORD *)_SI)[3] ^= rk[3]; #else (DWORD *)_SI = (DWORD *)&(out[BLOCKSIZE-BLOCKCOLUMNS]); for(j = BLOCKCOLUMNS; j >0; j--) *((DWORD *)_SI)-- ^= *rk--; #endif } } #ifdef DEBUG void print_a(cr_blockMultiDim a) { int i,j; for (j=0;j> 30)) + mti); /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */ /* In the previous versions, MSBs of the seed affect */ /* only MSBs of the array mt[]. */ /* 2002/01/09 modified by Makoto Matsumoto */ mt[mti] &= 0xffffffffUL; /* for >32 bit machines */ } } /* initialize by an array with array-length */ /* init_key is the array for initializing keys */ /* key_length is its length */ /* slight change for C++, 2004/2/26 */ void init_by_array(unsigned long init_key[],int key_length) { int i, j, k; init_genrand(19650218UL); i=1; j=0; k = (N>key_length ? N : key_length); for (; k; k--) { mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1664525UL)) + init_key[j] + j; /* non linear */ mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */ i++; j++; if (i>=N) { mt[0] = mt[N-1]; i=1; } if (j>=key_length) j=0; } for (k=N-1; k; k--) { mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1566083941UL)) - i; /* non linear */ mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */ i++; if (i>=N) { mt[0] = mt[N-1]; i=1; } } mt[0] = 0x80000000UL; /* MSB is 1; assuring non-zero initial array */ } /* generates a random number on [0,0xffffffff]-interval */ unsigned long genrand_int32(void) { unsigned long y; static unsigned long mag01[2]={0x0UL, MATRIX_A}; /* mag01[x] = x * MATRIX_A for x=0,1 */ if (mti >= N) { /* generate N WORDs at one time */ int kk; if (mti == N+1) /* if init_genrand() has not been called, */ init_genrand(5489UL); /* a default initial seed is used */ for (kk=0;kk> 1) ^ mag01[y & 0x1UL]; } for (;kk> 1) ^ mag01[y & 0x1UL]; } y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK); mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1UL]; mti = 0; } y = mt[mti++]; /* Tempering */ y ^= (y >> 11); y ^= (y << 7) & 0x9d2c5680UL; y ^= (y << 15) & 0xefc60000UL; y ^= (y >> 18); return y; } //#define AES_IN_KERNEL #ifdef AES_IN_KERNEL /* * InitAesForPort * * Transfer AES Data from Helper app to driver Extension * Send Init Vector to Device Server */ void InitAesForPort ( port_mapping *port ) { port->EncryptLeft = 0; port->DecryptLeft = 0; for (i = 0; i < INIT_VECTOR_LEN; i++) { port->EncryptVector[i] = genrand_int32(); port->DecryptVector[i] = port->EncryptVector[i]; } AtoIntelH(port->aes_key, port->aes_key_bytes, sizeof(port->aes_key_bytes)); aes_key_init( &port->AES_Encryption_Key, port->KeyBytes, port->KeyLength ); } int SendAESInitVector ( port_mapping *port ) { int status; write_net_bf( port->socket, port->EncryptVector, INIT_VECTOR_LEN, &status ); return status; } write_aes_bf( port_mapping *port, char far *buf, int size, int status ) { aes_byte_encrypt( &port->AES_Encryption_Key, port->EncryptVector, buf, size, buf, &port->EncryptLeft, 1); return write_net_bf( port->socket, buf, size, &status ); } #endif #endif // SCPR