📄 rijndael_api.c
字号:
size_t i, nr_blocks, extra; word32 in[4], out[4], iv[4]; word8 t; nr_blocks= length / 16; if ((extra= (length % 16)) > 0) { if (nr_blocks == 0) return RD_BAD_BLOCK_LENGTH; nr_blocks--; } blockcpy(iv, IV); if (aligned2(inp, outp)) { for (i= 0; i < nr_blocks; i++) { rijndael_Decrypt(inp, out, key->decsched, key->rounds); out[0] ^= iv[0]; out[1] ^= iv[1]; out[2] ^= iv[2]; out[3] ^= iv[3]; iv[0] = W(inp)[0]; iv[1] = W(inp)[1]; iv[2] = W(inp)[2]; iv[3] = W(inp)[3]; W(outp)[0] = out[0]; W(outp)[1] = out[1]; W(outp)[2] = out[2]; W(outp)[3] = out[3]; inp += 16; outp += 16; } } else { for (i= 0; i < nr_blocks; i++) { blockcpy(in, inp); rijndael_Decrypt(in, out, key->decsched, key->rounds); out[0] ^= iv[0]; out[1] ^= iv[1]; out[2] ^= iv[2]; out[3] ^= iv[3]; iv[0] = in[0]; iv[1] = in[1]; iv[2] = in[2]; iv[3] = in[3]; blockcpy(outp, out); inp += 16; outp += 16; } } if (extra > 0) { blockcpy(in, inp); blockcpy(IV, in); rijndael_Decrypt(in, out, key->decsched, key->rounds); for (i= 0; i < extra; i++) { t= B(out)[i] ^ inp[16 + i]; B(out)[i] = inp[16 + i]; outp[16 + i] = t; } rijndael_Decrypt(out, out, key->decsched, key->rounds); out[0] ^= iv[0]; out[1] ^= iv[1]; out[2] ^= iv[2]; out[3] ^= iv[3]; blockcpy(outp, out); } else { blockcpy(IV, iv); } return length;}ssize_t rijndael_cfb1_encrypt(rd_keyinstance *key, const void *input, void *output, size_t length, void *IV){ /* Encrypt blocks of data in Cypher Feedback mode, 1 bit at a time. */ const word8 *inp= input; word8 *outp= output; word8 t; size_t i; int b; word32 iv[4], civ[4]; blockcpy(iv, IV); for (i= 0; i < length; i++) { t= *inp++; for (b= 0; b < 8; b++) { rijndael_Encrypt(iv, civ, key->encsched, key->rounds); t ^= (B(civ)[0] & 0x80) >> b; B(iv)[ 0] = (B(iv)[ 0] << 1) | (B(iv)[ 1] >> 7); B(iv)[ 1] = (B(iv)[ 1] << 1) | (B(iv)[ 2] >> 7); B(iv)[ 2] = (B(iv)[ 2] << 1) | (B(iv)[ 3] >> 7); B(iv)[ 3] = (B(iv)[ 3] << 1) | (B(iv)[ 4] >> 7); B(iv)[ 4] = (B(iv)[ 4] << 1) | (B(iv)[ 5] >> 7); B(iv)[ 5] = (B(iv)[ 5] << 1) | (B(iv)[ 6] >> 7); B(iv)[ 6] = (B(iv)[ 6] << 1) | (B(iv)[ 7] >> 7); B(iv)[ 7] = (B(iv)[ 7] << 1) | (B(iv)[ 8] >> 7); B(iv)[ 8] = (B(iv)[ 8] << 1) | (B(iv)[ 9] >> 7); B(iv)[ 9] = (B(iv)[ 9] << 1) | (B(iv)[10] >> 7); B(iv)[10] = (B(iv)[10] << 1) | (B(iv)[11] >> 7); B(iv)[11] = (B(iv)[11] << 1) | (B(iv)[12] >> 7); B(iv)[12] = (B(iv)[12] << 1) | (B(iv)[13] >> 7); B(iv)[13] = (B(iv)[13] << 1) | (B(iv)[14] >> 7); B(iv)[14] = (B(iv)[14] << 1) | (B(iv)[15] >> 7); B(iv)[15] = (B(iv)[15] << 1) | ((t >> (7-b)) & 1); } *outp++ = t; } blockcpy(IV, iv); return length;}ssize_t rijndael_cfb1_decrypt(rd_keyinstance *key, const void *input, void *output, size_t length, void *IV){ /* Decrypt blocks of data in Cypher Feedback mode, 1 bit at a time. */ const word8 *inp= input; word8 *outp= output; word8 t; size_t i; int b; word32 iv[4], civ[4]; blockcpy(iv, IV); for (i= 0; i < length; i++) { t= *inp++; for (b= 0; b < 8; b++) { rijndael_Encrypt(iv, civ, key->encsched, key->rounds); B(iv)[ 0] = (B(iv)[ 0] << 1) | (B(iv)[ 1] >> 7); B(iv)[ 1] = (B(iv)[ 1] << 1) | (B(iv)[ 2] >> 7); B(iv)[ 2] = (B(iv)[ 2] << 1) | (B(iv)[ 3] >> 7); B(iv)[ 3] = (B(iv)[ 3] << 1) | (B(iv)[ 4] >> 7); B(iv)[ 4] = (B(iv)[ 4] << 1) | (B(iv)[ 5] >> 7); B(iv)[ 5] = (B(iv)[ 5] << 1) | (B(iv)[ 6] >> 7); B(iv)[ 6] = (B(iv)[ 6] << 1) | (B(iv)[ 7] >> 7); B(iv)[ 7] = (B(iv)[ 7] << 1) | (B(iv)[ 8] >> 7); B(iv)[ 8] = (B(iv)[ 8] << 1) | (B(iv)[ 9] >> 7); B(iv)[ 9] = (B(iv)[ 9] << 1) | (B(iv)[10] >> 7); B(iv)[10] = (B(iv)[10] << 1) | (B(iv)[11] >> 7); B(iv)[11] = (B(iv)[11] << 1) | (B(iv)[12] >> 7); B(iv)[12] = (B(iv)[12] << 1) | (B(iv)[13] >> 7); B(iv)[13] = (B(iv)[13] << 1) | (B(iv)[14] >> 7); B(iv)[14] = (B(iv)[14] << 1) | (B(iv)[15] >> 7); B(iv)[15] = (B(iv)[15] << 1) | ((t >> (7-b)) & 1); t ^= (B(civ)[0] & 0x80) >> b; } *outp++ = t; } blockcpy(IV, iv); return length;}ssize_t rijndael_cfb8_encrypt(rd_keyinstance *key, const void *input, void *output, size_t length, void *IV){ /* Encrypt blocks of data in Cypher Feedback mode, 8 bits at a time. */ const word8 *inp= input; word8 *outp= output; word8 t; size_t i; word32 iv[4], civ[4]; blockcpy(iv, IV); for (i= 0; i < length; i++) { t= *inp++; rijndael_Encrypt(iv, civ, key->encsched, key->rounds); t ^= B(civ)[0]; B(iv)[ 0] = B(iv)[ 1]; B(iv)[ 1] = B(iv)[ 2]; B(iv)[ 2] = B(iv)[ 3]; B(iv)[ 3] = B(iv)[ 4]; B(iv)[ 4] = B(iv)[ 5]; B(iv)[ 5] = B(iv)[ 6]; B(iv)[ 6] = B(iv)[ 7]; B(iv)[ 7] = B(iv)[ 8]; B(iv)[ 8] = B(iv)[ 9]; B(iv)[ 9] = B(iv)[10]; B(iv)[10] = B(iv)[11]; B(iv)[11] = B(iv)[12]; B(iv)[12] = B(iv)[13]; B(iv)[13] = B(iv)[14]; B(iv)[14] = B(iv)[15]; B(iv)[15] = t; *outp++ = t; } blockcpy(IV, iv); return length;}ssize_t rijndael_cfb8_decrypt(rd_keyinstance *key, const void *input, void *output, size_t length, void *IV){ /* Decrypt blocks of data in Cypher Feedback mode, 1 byte at a time. */ const word8 *inp= input; word8 *outp= output; word8 t; size_t i; word32 iv[4], civ[4]; blockcpy(iv, IV); for (i= 0; i < length; i++) { t= *inp++; rijndael_Encrypt(iv, civ, key->encsched, key->rounds); B(iv)[ 0] = B(iv)[ 1]; B(iv)[ 1] = B(iv)[ 2]; B(iv)[ 2] = B(iv)[ 3]; B(iv)[ 3] = B(iv)[ 4]; B(iv)[ 4] = B(iv)[ 5]; B(iv)[ 5] = B(iv)[ 6]; B(iv)[ 6] = B(iv)[ 7]; B(iv)[ 7] = B(iv)[ 8]; B(iv)[ 8] = B(iv)[ 9]; B(iv)[ 9] = B(iv)[10]; B(iv)[10] = B(iv)[11]; B(iv)[11] = B(iv)[12]; B(iv)[12] = B(iv)[13]; B(iv)[13] = B(iv)[14]; B(iv)[14] = B(iv)[15]; B(iv)[15] = t; t ^= B(civ)[0]; *outp++ = t; } blockcpy(IV, iv); return length;}ssize_t rijndael_pad(void *input, size_t length){ /* Adds at most one block of RFC-2040 style padding to the input to make * it a whole number of blocks for easier encryption. To be used if the * input may be less then one block in size, otherwise let the encryption * routines use cypher stealing. The input buffer should allow enough * space for the padding. The new length of the input is returned. */ word8 *inp= input; size_t padlen; /* Add padding up until the next block boundary. */ padlen= 16 - (length % 16); memset(inp + length, padlen, padlen); return length + padlen;}ssize_t rijndael_unpad(const void *input, size_t length){ /* Remove RFC-2040 style padding after decryption. The true length of * the input is returned, or the usual errors if the padding is incorrect. */ const word8 *inp= input; size_t i, padlen; if (length == 0 || (length % 16) != 0) return RD_BAD_BLOCK_LENGTH; padlen = inp[length-1]; if (padlen <= 0 || padlen > 16) return RD_BAD_DATA; for (i= 2; i <= padlen; i++) { if (inp[length-i] != padlen) return RD_BAD_DATA; } return length - padlen;}#ifdef INTERMEDIATE_VALUE_KATvoid cipherEncryptUpdateRounds(rd_keyinstance *key, const void *input, void *output, int rounds){ /* Encrypt a block only a specified number of rounds. */ word8 block[4][4]; blockcpy(block, input); rijndaelEncryptRound(block, key->encsched, key->rounds, rounds); blockcpy(output, block);}void cipherDecryptUpdateRounds(rd_keyinstance *key, const void *input, void *output, int rounds){ /* Decrypt a block only a specified number of rounds. */ word8 block[4][4]; blockcpy(block, input); rijndaelDecryptRound(block, key->decsched, key->rounds, rounds); blockcpy(output, block);}#endif /* INTERMEDIATE_VALUE_KAT *//* * $PchId: rijndael_api.c,v 1.2 2001/01/10 22:01:20 philip Exp $ */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -