/* rijndael_key_expansion * * Generate the expanded key from the key input by the user. */ static SECStatus rijndael_key_expansion(AESContext *cx, const unsigned char *key, unsigned int Nk) { unsigned int i; PRUint32 *W; PRUint32 *pW; PRUint32 tmp; unsigned int round_key_words = cx->Nb * (cx->Nr + 1); if (Nk == 7) return rijndael_key_expansion7(cx, key, Nk); W = cx->expandedKey; /* The first Nk words contain the input cipher key */ memcpy(W, key, Nk * 4); i = Nk; pW = W + i - 1; /* Loop over all sets of Nk words, except the last */ while (i < round_key_words - Nk) { tmp = *pW++; tmp = SUBBYTE(ROTBYTE(tmp)) ^ Rcon[i / Nk - 1]; *pW = W[i++ - Nk] ^ tmp; tmp = *pW++; *pW = W[i++ - Nk] ^ tmp; tmp = *pW++; *pW = W[i++ - Nk] ^ tmp; tmp = *pW++; *pW = W[i++ - Nk] ^ tmp; if (Nk == 4) continue; switch (Nk) { case 8: tmp = *pW++; tmp = SUBBYTE(tmp); *pW = W[i++ - Nk] ^ tmp; case 7: tmp = *pW++; *pW = W[i++ - Nk] ^ tmp; case 6: tmp = *pW++; *pW = W[i++ - Nk] ^ tmp; case 5: tmp = *pW++; *pW = W[i++ - Nk] ^ tmp; } } /* Generate the last word */ tmp = *pW++; tmp = SUBBYTE(ROTBYTE(tmp)) ^ Rcon[i / Nk - 1]; *pW = W[i++ - Nk] ^ tmp; /* There may be overflow here, if Nk % (Nb * (Nr + 1)) > 0. However, * since the above loop generated all but the last Nk key words, there * is no more need for the SubByte transformation. */ if (Nk < 8) { for (; i < round_key_words; ++i) { tmp = *pW++; *pW = W[i - Nk] ^ tmp; } } else { /* except in the case when Nk == 8. Then one more SubByte may have * to be performed, at i % Nk == 4. */ for (; i < round_key_words; ++i) { tmp = *pW++; if (i % Nk == 4) tmp = SUBBYTE(tmp); *pW = W[i - Nk] ^ tmp; } } return SECSuccess; }
void KeyExpansion(RijndaelContextPtr context) { int i; unsigned int tmp; //256位有32个字节,8个字长 //密钥字长 int nk = context->nk; //明文字长 int nb = context->nb; //轮数 int nr = context->nr; unsigned char* keyPtr = context->cryptKey; //nr最大为14,nb最大为8,则需要的矩阵列为nb*(nr+1)=8*15=120 //轮密钥 //unsigned long roundKey[120] = {0}; context->roundKey[0] = GETINT32(keyPtr,0,nk);//第一列 context->roundKey[1] = GETINT32(keyPtr,1,nk);//第二列 context->roundKey[2] = GETINT32(keyPtr,2,nk);//第三列 context->roundKey[3] = GETINT32(keyPtr,3,nk);//第四列 if (nk >= (KeySize_192/4)) { context->roundKey[4] = GETINT32(keyPtr,4,nk); context->roundKey[5] = GETINT32(keyPtr,5,nk); } else if (nk >= (KeySize_256/4)) { context->roundKey[6] = GETINT32(keyPtr,6,nk); context->roundKey[7] = GETINT32(keyPtr,7,nk); } //轮数为明文和密文中长度更大值的字长+4 for (i = nk;i<(nb*(nr+1)); i++) { tmp = context->roundKey[i-1]; if (i % nk == 0) { tmp = ROTL(tmp,8,32); tmp = SUBBYTE(tmp); tmp ^= rcon[i / nk]; } else if ((nk > (KeySize_192/4)) && (i%4 == 0)) { tmp = SUBBYTE(tmp); } context->roundKey[i] = context->roundKey[i - nk] ^ tmp; } //将不需要的清0 memset(&context->roundKey[nb*(nr+1)],0,sizeof(context->roundKey) - sizeof(context->roundKey[0]) * (nb*(nr+1))); //轮密钥还可以加强,扩展 }
/* rijndael_key_expansion7 * * Generate the expanded key from the key input by the user. * XXX * Nk == 7 (224 key bits) is a weird case. Since Nk > 6, an added SubByte * transformation is done periodically. The period is every 4 bytes, and * since 7%4 != 0 this happens at different times for each key word (unlike * Nk == 8 where it happens twice in every key word, in the same positions). * For now, I'm implementing this case "dumbly", w/o any unrolling. */ static SECStatus rijndael_key_expansion7(AESContext *cx, const unsigned char *key, unsigned int Nk) { unsigned int i; PRUint32 *W; PRUint32 *pW; PRUint32 tmp; W = cx->expandedKey; /* 1. the first Nk words contain the cipher key */ memcpy(W, key, Nk * 4); i = Nk; /* 2. loop until full expanded key is obtained */ pW = W + i - 1; for (; i < cx->Nb * (cx->Nr + 1); ++i) { tmp = *pW++; if (i % Nk == 0) tmp = SUBBYTE(ROTBYTE(tmp)) ^ Rcon[i / Nk - 1]; else if (i % Nk == 4) tmp = SUBBYTE(tmp); *pW = W[i - Nk] ^ tmp; } return SECSuccess; }
/** * 将明文替换 */ void SubByte(RijndaelContextPtr context,unsigned long state[]) { /* statePtr->v0 = SUBBYTE(statePtr->v0); statePtr->v1 = SUBBYTE(statePtr->v1); statePtr->v2 = SUBBYTE(statePtr->v2); statePtr->v3 = SUBBYTE(statePtr->v3); if (contextPtr->nb >= (KeySize_192/4)) { statePtr->v4 = SUBBYTE(statePtr->v4); statePtr->v5 = SUBBYTE(statePtr->v5); } if (contextPtr->nb >= (KeySize_256/4)) { statePtr->v6 = SUBBYTE(statePtr->v6); statePtr->v7 = SUBBYTE(statePtr->v7); } */ unsigned int i; for (i=0; i<context->nb; i++) { state[i] = SUBBYTE(state[i]); } }