1f9f848faSopenharmony_ci/* $KAME: rijndael-api-fst.c,v 1.10 2001/05/27 09:34:18 itojun Exp $ */ 2f9f848faSopenharmony_ci 3f9f848faSopenharmony_ci/* 4f9f848faSopenharmony_ci * rijndael-api-fst.c v2.3 April '2000 5f9f848faSopenharmony_ci * 6f9f848faSopenharmony_ci * Optimised ANSI C code 7f9f848faSopenharmony_ci * 8f9f848faSopenharmony_ci * authors: v1.0: Antoon Bosselaers 9f9f848faSopenharmony_ci * v2.0: Vincent Rijmen 10f9f848faSopenharmony_ci * v2.1: Vincent Rijmen 11f9f848faSopenharmony_ci * v2.2: Vincent Rijmen 12f9f848faSopenharmony_ci * v2.3: Paulo Barreto 13f9f848faSopenharmony_ci * v2.4: Vincent Rijmen 14f9f848faSopenharmony_ci * 15f9f848faSopenharmony_ci * This code is placed in the public domain. 16f9f848faSopenharmony_ci */ 17f9f848faSopenharmony_ci 18f9f848faSopenharmony_ci#include <sys/cdefs.h> 19f9f848faSopenharmony_ci 20f9f848faSopenharmony_ci#include <sys/types.h> 21f9f848faSopenharmony_ci#include <sys/param.h> 22f9f848faSopenharmony_ci#ifdef _KERNEL 23f9f848faSopenharmony_ci#include <sys/systm.h> 24f9f848faSopenharmony_ci#else 25f9f848faSopenharmony_ci#include <string.h> 26f9f848faSopenharmony_ci#endif 27f9f848faSopenharmony_ci 28f9f848faSopenharmony_ci#include <crypto/rijndael/rijndael_local.h> 29f9f848faSopenharmony_ci#include <crypto/rijndael/rijndael-api-fst.h> 30f9f848faSopenharmony_ci 31f9f848faSopenharmony_ci#ifndef TRUE 32f9f848faSopenharmony_ci#define TRUE 1 33f9f848faSopenharmony_ci#endif 34f9f848faSopenharmony_ci 35f9f848faSopenharmony_citypedef uint8_t BYTE; 36f9f848faSopenharmony_ci 37f9f848faSopenharmony_ciint rijndael_makeKey(keyInstance *key, BYTE direction, int keyLen, 38f9f848faSopenharmony_ci const char *keyMaterial) { 39f9f848faSopenharmony_ci 40f9f848faSopenharmony_ci if (key == NULL) { 41f9f848faSopenharmony_ci return BAD_KEY_INSTANCE; 42f9f848faSopenharmony_ci } 43f9f848faSopenharmony_ci 44f9f848faSopenharmony_ci if ((direction == DIR_ENCRYPT) || (direction == DIR_DECRYPT)) { 45f9f848faSopenharmony_ci key->direction = direction; 46f9f848faSopenharmony_ci } else { 47f9f848faSopenharmony_ci return BAD_KEY_DIR; 48f9f848faSopenharmony_ci } 49f9f848faSopenharmony_ci 50f9f848faSopenharmony_ci if ((keyLen == 128) || (keyLen == 192) || (keyLen == 256)) { 51f9f848faSopenharmony_ci key->keyLen = keyLen; 52f9f848faSopenharmony_ci } else { 53f9f848faSopenharmony_ci return BAD_KEY_MAT; 54f9f848faSopenharmony_ci } 55f9f848faSopenharmony_ci 56f9f848faSopenharmony_ci if (keyMaterial != NULL) { 57f9f848faSopenharmony_ci memcpy(key->keyMaterial, keyMaterial, keyLen/8); 58f9f848faSopenharmony_ci } 59f9f848faSopenharmony_ci 60f9f848faSopenharmony_ci /* initialize key schedule: */ 61f9f848faSopenharmony_ci if (direction == DIR_ENCRYPT) { 62f9f848faSopenharmony_ci key->Nr = rijndaelKeySetupEnc(key->rk, (const u8 *)(key->keyMaterial), keyLen); 63f9f848faSopenharmony_ci } else { 64f9f848faSopenharmony_ci key->Nr = rijndaelKeySetupDec(key->rk, (const u8 *)(key->keyMaterial), keyLen); 65f9f848faSopenharmony_ci } 66f9f848faSopenharmony_ci rijndaelKeySetupEnc(key->ek, (const u8 *)(key->keyMaterial), keyLen); 67f9f848faSopenharmony_ci return TRUE; 68f9f848faSopenharmony_ci} 69f9f848faSopenharmony_ci 70f9f848faSopenharmony_ciint rijndael_cipherInit(cipherInstance *cipher, BYTE mode, char *IV) { 71f9f848faSopenharmony_ci if ((mode == MODE_ECB) || (mode == MODE_CBC) || (mode == MODE_CFB1)) { 72f9f848faSopenharmony_ci cipher->mode = mode; 73f9f848faSopenharmony_ci } else { 74f9f848faSopenharmony_ci return BAD_CIPHER_MODE; 75f9f848faSopenharmony_ci } 76f9f848faSopenharmony_ci if (IV != NULL) { 77f9f848faSopenharmony_ci memcpy(cipher->IV, IV, RIJNDAEL_MAX_IV_SIZE); 78f9f848faSopenharmony_ci } else { 79f9f848faSopenharmony_ci memset(cipher->IV, 0, RIJNDAEL_MAX_IV_SIZE); 80f9f848faSopenharmony_ci } 81f9f848faSopenharmony_ci return TRUE; 82f9f848faSopenharmony_ci} 83f9f848faSopenharmony_ci 84f9f848faSopenharmony_ciint rijndael_blockEncrypt(cipherInstance *cipher, keyInstance *key, 85f9f848faSopenharmony_ci const BYTE *input, int inputLen, BYTE *outBuffer) { 86f9f848faSopenharmony_ci int i, k, numBlocks; 87f9f848faSopenharmony_ci uint8_t block[16], iv[4][4]; 88f9f848faSopenharmony_ci 89f9f848faSopenharmony_ci if (cipher == NULL || 90f9f848faSopenharmony_ci key == NULL || 91f9f848faSopenharmony_ci key->direction == DIR_DECRYPT) { 92f9f848faSopenharmony_ci return BAD_CIPHER_STATE; 93f9f848faSopenharmony_ci } 94f9f848faSopenharmony_ci if (input == NULL || inputLen <= 0) { 95f9f848faSopenharmony_ci return 0; /* nothing to do */ 96f9f848faSopenharmony_ci } 97f9f848faSopenharmony_ci 98f9f848faSopenharmony_ci numBlocks = inputLen/128; 99f9f848faSopenharmony_ci 100f9f848faSopenharmony_ci switch (cipher->mode) { 101f9f848faSopenharmony_ci case MODE_ECB: 102f9f848faSopenharmony_ci for (i = numBlocks; i > 0; i--) { 103f9f848faSopenharmony_ci rijndaelEncrypt(key->rk, key->Nr, input, outBuffer); 104f9f848faSopenharmony_ci input += 16; 105f9f848faSopenharmony_ci outBuffer += 16; 106f9f848faSopenharmony_ci } 107f9f848faSopenharmony_ci break; 108f9f848faSopenharmony_ci 109f9f848faSopenharmony_ci case MODE_CBC: 110f9f848faSopenharmony_ci#if 1 /*STRICT_ALIGN*/ 111f9f848faSopenharmony_ci memcpy(block, cipher->IV, 16); 112f9f848faSopenharmony_ci memcpy(iv, input, 16); 113f9f848faSopenharmony_ci ((uint32_t*)block)[0] ^= ((uint32_t*)iv)[0]; 114f9f848faSopenharmony_ci ((uint32_t*)block)[1] ^= ((uint32_t*)iv)[1]; 115f9f848faSopenharmony_ci ((uint32_t*)block)[2] ^= ((uint32_t*)iv)[2]; 116f9f848faSopenharmony_ci ((uint32_t*)block)[3] ^= ((uint32_t*)iv)[3]; 117f9f848faSopenharmony_ci#else 118f9f848faSopenharmony_ci ((uint32_t*)block)[0] = ((uint32_t*)cipher->IV)[0] ^ ((uint32_t*)input)[0]; 119f9f848faSopenharmony_ci ((uint32_t*)block)[1] = ((uint32_t*)cipher->IV)[1] ^ ((uint32_t*)input)[1]; 120f9f848faSopenharmony_ci ((uint32_t*)block)[2] = ((uint32_t*)cipher->IV)[2] ^ ((uint32_t*)input)[2]; 121f9f848faSopenharmony_ci ((uint32_t*)block)[3] = ((uint32_t*)cipher->IV)[3] ^ ((uint32_t*)input)[3]; 122f9f848faSopenharmony_ci#endif 123f9f848faSopenharmony_ci rijndaelEncrypt(key->rk, key->Nr, block, outBuffer); 124f9f848faSopenharmony_ci input += 16; 125f9f848faSopenharmony_ci for (i = numBlocks - 1; i > 0; i--) { 126f9f848faSopenharmony_ci#if 1 /*STRICT_ALIGN*/ 127f9f848faSopenharmony_ci memcpy(block, outBuffer, 16); 128f9f848faSopenharmony_ci memcpy(iv, input, 16); 129f9f848faSopenharmony_ci ((uint32_t*)block)[0] ^= ((uint32_t*)iv)[0]; 130f9f848faSopenharmony_ci ((uint32_t*)block)[1] ^= ((uint32_t*)iv)[1]; 131f9f848faSopenharmony_ci ((uint32_t*)block)[2] ^= ((uint32_t*)iv)[2]; 132f9f848faSopenharmony_ci ((uint32_t*)block)[3] ^= ((uint32_t*)iv)[3]; 133f9f848faSopenharmony_ci#else 134f9f848faSopenharmony_ci ((uint32_t*)block)[0] = ((uint32_t*)outBuffer)[0] ^ ((uint32_t*)input)[0]; 135f9f848faSopenharmony_ci ((uint32_t*)block)[1] = ((uint32_t*)outBuffer)[1] ^ ((uint32_t*)input)[1]; 136f9f848faSopenharmony_ci ((uint32_t*)block)[2] = ((uint32_t*)outBuffer)[2] ^ ((uint32_t*)input)[2]; 137f9f848faSopenharmony_ci ((uint32_t*)block)[3] = ((uint32_t*)outBuffer)[3] ^ ((uint32_t*)input)[3]; 138f9f848faSopenharmony_ci#endif 139f9f848faSopenharmony_ci outBuffer += 16; 140f9f848faSopenharmony_ci rijndaelEncrypt(key->rk, key->Nr, block, outBuffer); 141f9f848faSopenharmony_ci input += 16; 142f9f848faSopenharmony_ci } 143f9f848faSopenharmony_ci break; 144f9f848faSopenharmony_ci 145f9f848faSopenharmony_ci case MODE_CFB1: 146f9f848faSopenharmony_ci#if 1 /*STRICT_ALIGN*/ 147f9f848faSopenharmony_ci memcpy(iv, cipher->IV, 16); 148f9f848faSopenharmony_ci#else /* !STRICT_ALIGN */ 149f9f848faSopenharmony_ci *((uint32_t*)iv[0]) = *((uint32_t*)(cipher->IV )); 150f9f848faSopenharmony_ci *((uint32_t*)iv[1]) = *((uint32_t*)(cipher->IV+ 4)); 151f9f848faSopenharmony_ci *((uint32_t*)iv[2]) = *((uint32_t*)(cipher->IV+ 8)); 152f9f848faSopenharmony_ci *((uint32_t*)iv[3]) = *((uint32_t*)(cipher->IV+12)); 153f9f848faSopenharmony_ci#endif /* ?STRICT_ALIGN */ 154f9f848faSopenharmony_ci for (i = numBlocks; i > 0; i--) { 155f9f848faSopenharmony_ci for (k = 0; k < 128; k++) { 156f9f848faSopenharmony_ci *((uint32_t*) block ) = *((uint32_t*)iv[0]); 157f9f848faSopenharmony_ci *((uint32_t*)(block+ 4)) = *((uint32_t*)iv[1]); 158f9f848faSopenharmony_ci *((uint32_t*)(block+ 8)) = *((uint32_t*)iv[2]); 159f9f848faSopenharmony_ci *((uint32_t*)(block+12)) = *((uint32_t*)iv[3]); 160f9f848faSopenharmony_ci rijndaelEncrypt(key->ek, key->Nr, block, 161f9f848faSopenharmony_ci block); 162f9f848faSopenharmony_ci outBuffer[k/8] ^= (block[0] & 0x80) >> (k & 7); 163f9f848faSopenharmony_ci iv[0][0] = (iv[0][0] << 1) | (iv[0][1] >> 7); 164f9f848faSopenharmony_ci iv[0][1] = (iv[0][1] << 1) | (iv[0][2] >> 7); 165f9f848faSopenharmony_ci iv[0][2] = (iv[0][2] << 1) | (iv[0][3] >> 7); 166f9f848faSopenharmony_ci iv[0][3] = (iv[0][3] << 1) | (iv[1][0] >> 7); 167f9f848faSopenharmony_ci iv[1][0] = (iv[1][0] << 1) | (iv[1][1] >> 7); 168f9f848faSopenharmony_ci iv[1][1] = (iv[1][1] << 1) | (iv[1][2] >> 7); 169f9f848faSopenharmony_ci iv[1][2] = (iv[1][2] << 1) | (iv[1][3] >> 7); 170f9f848faSopenharmony_ci iv[1][3] = (iv[1][3] << 1) | (iv[2][0] >> 7); 171f9f848faSopenharmony_ci iv[2][0] = (iv[2][0] << 1) | (iv[2][1] >> 7); 172f9f848faSopenharmony_ci iv[2][1] = (iv[2][1] << 1) | (iv[2][2] >> 7); 173f9f848faSopenharmony_ci iv[2][2] = (iv[2][2] << 1) | (iv[2][3] >> 7); 174f9f848faSopenharmony_ci iv[2][3] = (iv[2][3] << 1) | (iv[3][0] >> 7); 175f9f848faSopenharmony_ci iv[3][0] = (iv[3][0] << 1) | (iv[3][1] >> 7); 176f9f848faSopenharmony_ci iv[3][1] = (iv[3][1] << 1) | (iv[3][2] >> 7); 177f9f848faSopenharmony_ci iv[3][2] = (iv[3][2] << 1) | (iv[3][3] >> 7); 178f9f848faSopenharmony_ci iv[3][3] = (iv[3][3] << 1) | ((outBuffer[k/8] >> (7-(k&7))) & 1); 179f9f848faSopenharmony_ci } 180f9f848faSopenharmony_ci } 181f9f848faSopenharmony_ci break; 182f9f848faSopenharmony_ci 183f9f848faSopenharmony_ci default: 184f9f848faSopenharmony_ci return BAD_CIPHER_STATE; 185f9f848faSopenharmony_ci } 186f9f848faSopenharmony_ci 187f9f848faSopenharmony_ci explicit_bzero(block, sizeof(block)); 188f9f848faSopenharmony_ci return 128*numBlocks; 189f9f848faSopenharmony_ci} 190f9f848faSopenharmony_ci 191f9f848faSopenharmony_ci/** 192f9f848faSopenharmony_ci * Encrypt data partitioned in octets, using RFC 2040-like padding. 193f9f848faSopenharmony_ci * 194f9f848faSopenharmony_ci * @param input data to be encrypted (octet sequence) 195f9f848faSopenharmony_ci * @param inputOctets input length in octets (not bits) 196f9f848faSopenharmony_ci * @param outBuffer encrypted output data 197f9f848faSopenharmony_ci * 198f9f848faSopenharmony_ci * @return length in octets (not bits) of the encrypted output buffer. 199f9f848faSopenharmony_ci */ 200f9f848faSopenharmony_ciint rijndael_padEncrypt(cipherInstance *cipher, keyInstance *key, 201f9f848faSopenharmony_ci const BYTE *input, int inputOctets, BYTE *outBuffer) { 202f9f848faSopenharmony_ci int i, numBlocks, padLen; 203f9f848faSopenharmony_ci uint8_t block[16], *iv, *cp; 204f9f848faSopenharmony_ci 205f9f848faSopenharmony_ci if (cipher == NULL || 206f9f848faSopenharmony_ci key == NULL || 207f9f848faSopenharmony_ci key->direction == DIR_DECRYPT) { 208f9f848faSopenharmony_ci return BAD_CIPHER_STATE; 209f9f848faSopenharmony_ci } 210f9f848faSopenharmony_ci if (input == NULL || inputOctets <= 0) { 211f9f848faSopenharmony_ci return 0; /* nothing to do */ 212f9f848faSopenharmony_ci } 213f9f848faSopenharmony_ci 214f9f848faSopenharmony_ci numBlocks = inputOctets/16; 215f9f848faSopenharmony_ci 216f9f848faSopenharmony_ci switch (cipher->mode) { 217f9f848faSopenharmony_ci case MODE_ECB: 218f9f848faSopenharmony_ci for (i = numBlocks; i > 0; i--) { 219f9f848faSopenharmony_ci rijndaelEncrypt(key->rk, key->Nr, input, outBuffer); 220f9f848faSopenharmony_ci input += 16; 221f9f848faSopenharmony_ci outBuffer += 16; 222f9f848faSopenharmony_ci } 223f9f848faSopenharmony_ci padLen = 16 - (inputOctets - 16*numBlocks); 224f9f848faSopenharmony_ci if (padLen <= 0 || padLen > 16) 225f9f848faSopenharmony_ci return BAD_CIPHER_STATE; 226f9f848faSopenharmony_ci memcpy(block, input, 16 - padLen); 227f9f848faSopenharmony_ci for (cp = block + 16 - padLen; cp < block + 16; cp++) 228f9f848faSopenharmony_ci *cp = padLen; 229f9f848faSopenharmony_ci rijndaelEncrypt(key->rk, key->Nr, block, outBuffer); 230f9f848faSopenharmony_ci break; 231f9f848faSopenharmony_ci 232f9f848faSopenharmony_ci case MODE_CBC: 233f9f848faSopenharmony_ci iv = cipher->IV; 234f9f848faSopenharmony_ci for (i = numBlocks; i > 0; i--) { 235f9f848faSopenharmony_ci ((uint32_t*)block)[0] = ((const uint32_t*)input)[0] ^ ((uint32_t*)iv)[0]; 236f9f848faSopenharmony_ci ((uint32_t*)block)[1] = ((const uint32_t*)input)[1] ^ ((uint32_t*)iv)[1]; 237f9f848faSopenharmony_ci ((uint32_t*)block)[2] = ((const uint32_t*)input)[2] ^ ((uint32_t*)iv)[2]; 238f9f848faSopenharmony_ci ((uint32_t*)block)[3] = ((const uint32_t*)input)[3] ^ ((uint32_t*)iv)[3]; 239f9f848faSopenharmony_ci rijndaelEncrypt(key->rk, key->Nr, block, outBuffer); 240f9f848faSopenharmony_ci iv = outBuffer; 241f9f848faSopenharmony_ci input += 16; 242f9f848faSopenharmony_ci outBuffer += 16; 243f9f848faSopenharmony_ci } 244f9f848faSopenharmony_ci padLen = 16 - (inputOctets - 16*numBlocks); 245f9f848faSopenharmony_ci if (padLen <= 0 || padLen > 16) 246f9f848faSopenharmony_ci return BAD_CIPHER_STATE; 247f9f848faSopenharmony_ci for (i = 0; i < 16 - padLen; i++) { 248f9f848faSopenharmony_ci block[i] = input[i] ^ iv[i]; 249f9f848faSopenharmony_ci } 250f9f848faSopenharmony_ci for (i = 16 - padLen; i < 16; i++) { 251f9f848faSopenharmony_ci block[i] = (BYTE)padLen ^ iv[i]; 252f9f848faSopenharmony_ci } 253f9f848faSopenharmony_ci rijndaelEncrypt(key->rk, key->Nr, block, outBuffer); 254f9f848faSopenharmony_ci break; 255f9f848faSopenharmony_ci 256f9f848faSopenharmony_ci default: 257f9f848faSopenharmony_ci return BAD_CIPHER_STATE; 258f9f848faSopenharmony_ci } 259f9f848faSopenharmony_ci 260f9f848faSopenharmony_ci explicit_bzero(block, sizeof(block)); 261f9f848faSopenharmony_ci return 16*(numBlocks + 1); 262f9f848faSopenharmony_ci} 263f9f848faSopenharmony_ci 264f9f848faSopenharmony_ciint rijndael_blockDecrypt(cipherInstance *cipher, keyInstance *key, 265f9f848faSopenharmony_ci const BYTE *input, int inputLen, BYTE *outBuffer) { 266f9f848faSopenharmony_ci int i, k, numBlocks; 267f9f848faSopenharmony_ci uint8_t block[16], iv[4][4]; 268f9f848faSopenharmony_ci 269f9f848faSopenharmony_ci if (cipher == NULL || 270f9f848faSopenharmony_ci key == NULL || 271f9f848faSopenharmony_ci (cipher->mode != MODE_CFB1 && key->direction == DIR_ENCRYPT)) { 272f9f848faSopenharmony_ci return BAD_CIPHER_STATE; 273f9f848faSopenharmony_ci } 274f9f848faSopenharmony_ci if (input == NULL || inputLen <= 0) { 275f9f848faSopenharmony_ci return 0; /* nothing to do */ 276f9f848faSopenharmony_ci } 277f9f848faSopenharmony_ci 278f9f848faSopenharmony_ci numBlocks = inputLen/128; 279f9f848faSopenharmony_ci 280f9f848faSopenharmony_ci switch (cipher->mode) { 281f9f848faSopenharmony_ci case MODE_ECB: 282f9f848faSopenharmony_ci for (i = numBlocks; i > 0; i--) { 283f9f848faSopenharmony_ci rijndaelDecrypt(key->rk, key->Nr, input, outBuffer); 284f9f848faSopenharmony_ci input += 16; 285f9f848faSopenharmony_ci outBuffer += 16; 286f9f848faSopenharmony_ci } 287f9f848faSopenharmony_ci break; 288f9f848faSopenharmony_ci 289f9f848faSopenharmony_ci case MODE_CBC: 290f9f848faSopenharmony_ci#if 1 /*STRICT_ALIGN */ 291f9f848faSopenharmony_ci memcpy(iv, cipher->IV, 16); 292f9f848faSopenharmony_ci#else 293f9f848faSopenharmony_ci *((uint32_t*)iv[0]) = *((uint32_t*)(cipher->IV )); 294f9f848faSopenharmony_ci *((uint32_t*)iv[1]) = *((uint32_t*)(cipher->IV+ 4)); 295f9f848faSopenharmony_ci *((uint32_t*)iv[2]) = *((uint32_t*)(cipher->IV+ 8)); 296f9f848faSopenharmony_ci *((uint32_t*)iv[3]) = *((uint32_t*)(cipher->IV+12)); 297f9f848faSopenharmony_ci#endif 298f9f848faSopenharmony_ci for (i = numBlocks; i > 0; i--) { 299f9f848faSopenharmony_ci rijndaelDecrypt(key->rk, key->Nr, input, block); 300f9f848faSopenharmony_ci ((uint32_t*)block)[0] ^= *((uint32_t*)iv[0]); 301f9f848faSopenharmony_ci ((uint32_t*)block)[1] ^= *((uint32_t*)iv[1]); 302f9f848faSopenharmony_ci ((uint32_t*)block)[2] ^= *((uint32_t*)iv[2]); 303f9f848faSopenharmony_ci ((uint32_t*)block)[3] ^= *((uint32_t*)iv[3]); 304f9f848faSopenharmony_ci#if 1 /*STRICT_ALIGN*/ 305f9f848faSopenharmony_ci memcpy(iv, input, 16); 306f9f848faSopenharmony_ci memcpy(outBuffer, block, 16); 307f9f848faSopenharmony_ci#else 308f9f848faSopenharmony_ci *((uint32_t*)iv[0]) = ((uint32_t*)input)[0]; ((uint32_t*)outBuffer)[0] = ((uint32_t*)block)[0]; 309f9f848faSopenharmony_ci *((uint32_t*)iv[1]) = ((uint32_t*)input)[1]; ((uint32_t*)outBuffer)[1] = ((uint32_t*)block)[1]; 310f9f848faSopenharmony_ci *((uint32_t*)iv[2]) = ((uint32_t*)input)[2]; ((uint32_t*)outBuffer)[2] = ((uint32_t*)block)[2]; 311f9f848faSopenharmony_ci *((uint32_t*)iv[3]) = ((uint32_t*)input)[3]; ((uint32_t*)outBuffer)[3] = ((uint32_t*)block)[3]; 312f9f848faSopenharmony_ci#endif 313f9f848faSopenharmony_ci input += 16; 314f9f848faSopenharmony_ci outBuffer += 16; 315f9f848faSopenharmony_ci } 316f9f848faSopenharmony_ci break; 317f9f848faSopenharmony_ci 318f9f848faSopenharmony_ci case MODE_CFB1: 319f9f848faSopenharmony_ci#if 1 /*STRICT_ALIGN */ 320f9f848faSopenharmony_ci memcpy(iv, cipher->IV, 16); 321f9f848faSopenharmony_ci#else 322f9f848faSopenharmony_ci *((uint32_t*)iv[0]) = *((uint32_t*)(cipher->IV)); 323f9f848faSopenharmony_ci *((uint32_t*)iv[1]) = *((uint32_t*)(cipher->IV+ 4)); 324f9f848faSopenharmony_ci *((uint32_t*)iv[2]) = *((uint32_t*)(cipher->IV+ 8)); 325f9f848faSopenharmony_ci *((uint32_t*)iv[3]) = *((uint32_t*)(cipher->IV+12)); 326f9f848faSopenharmony_ci#endif 327f9f848faSopenharmony_ci for (i = numBlocks; i > 0; i--) { 328f9f848faSopenharmony_ci for (k = 0; k < 128; k++) { 329f9f848faSopenharmony_ci *((uint32_t*) block ) = *((uint32_t*)iv[0]); 330f9f848faSopenharmony_ci *((uint32_t*)(block+ 4)) = *((uint32_t*)iv[1]); 331f9f848faSopenharmony_ci *((uint32_t*)(block+ 8)) = *((uint32_t*)iv[2]); 332f9f848faSopenharmony_ci *((uint32_t*)(block+12)) = *((uint32_t*)iv[3]); 333f9f848faSopenharmony_ci rijndaelEncrypt(key->ek, key->Nr, block, 334f9f848faSopenharmony_ci block); 335f9f848faSopenharmony_ci iv[0][0] = (iv[0][0] << 1) | (iv[0][1] >> 7); 336f9f848faSopenharmony_ci iv[0][1] = (iv[0][1] << 1) | (iv[0][2] >> 7); 337f9f848faSopenharmony_ci iv[0][2] = (iv[0][2] << 1) | (iv[0][3] >> 7); 338f9f848faSopenharmony_ci iv[0][3] = (iv[0][3] << 1) | (iv[1][0] >> 7); 339f9f848faSopenharmony_ci iv[1][0] = (iv[1][0] << 1) | (iv[1][1] >> 7); 340f9f848faSopenharmony_ci iv[1][1] = (iv[1][1] << 1) | (iv[1][2] >> 7); 341f9f848faSopenharmony_ci iv[1][2] = (iv[1][2] << 1) | (iv[1][3] >> 7); 342f9f848faSopenharmony_ci iv[1][3] = (iv[1][3] << 1) | (iv[2][0] >> 7); 343f9f848faSopenharmony_ci iv[2][0] = (iv[2][0] << 1) | (iv[2][1] >> 7); 344f9f848faSopenharmony_ci iv[2][1] = (iv[2][1] << 1) | (iv[2][2] >> 7); 345f9f848faSopenharmony_ci iv[2][2] = (iv[2][2] << 1) | (iv[2][3] >> 7); 346f9f848faSopenharmony_ci iv[2][3] = (iv[2][3] << 1) | (iv[3][0] >> 7); 347f9f848faSopenharmony_ci iv[3][0] = (iv[3][0] << 1) | (iv[3][1] >> 7); 348f9f848faSopenharmony_ci iv[3][1] = (iv[3][1] << 1) | (iv[3][2] >> 7); 349f9f848faSopenharmony_ci iv[3][2] = (iv[3][2] << 1) | (iv[3][3] >> 7); 350f9f848faSopenharmony_ci iv[3][3] = (iv[3][3] << 1) | ((input[k/8] >> (7-(k&7))) & 1); 351f9f848faSopenharmony_ci outBuffer[k/8] ^= (block[0] & 0x80) >> (k & 7); 352f9f848faSopenharmony_ci } 353f9f848faSopenharmony_ci } 354f9f848faSopenharmony_ci break; 355f9f848faSopenharmony_ci 356f9f848faSopenharmony_ci default: 357f9f848faSopenharmony_ci return BAD_CIPHER_STATE; 358f9f848faSopenharmony_ci } 359f9f848faSopenharmony_ci 360f9f848faSopenharmony_ci explicit_bzero(block, sizeof(block)); 361f9f848faSopenharmony_ci return 128*numBlocks; 362f9f848faSopenharmony_ci} 363f9f848faSopenharmony_ci 364f9f848faSopenharmony_ciint rijndael_padDecrypt(cipherInstance *cipher, keyInstance *key, 365f9f848faSopenharmony_ci const BYTE *input, int inputOctets, BYTE *outBuffer) { 366f9f848faSopenharmony_ci int i, numBlocks, padLen, rval; 367f9f848faSopenharmony_ci uint8_t block[16]; 368f9f848faSopenharmony_ci uint32_t iv[4]; 369f9f848faSopenharmony_ci 370f9f848faSopenharmony_ci if (cipher == NULL || 371f9f848faSopenharmony_ci key == NULL || 372f9f848faSopenharmony_ci key->direction == DIR_ENCRYPT) { 373f9f848faSopenharmony_ci return BAD_CIPHER_STATE; 374f9f848faSopenharmony_ci } 375f9f848faSopenharmony_ci if (input == NULL || inputOctets <= 0) { 376f9f848faSopenharmony_ci return 0; /* nothing to do */ 377f9f848faSopenharmony_ci } 378f9f848faSopenharmony_ci if (inputOctets % 16 != 0) { 379f9f848faSopenharmony_ci return BAD_DATA; 380f9f848faSopenharmony_ci } 381f9f848faSopenharmony_ci 382f9f848faSopenharmony_ci numBlocks = inputOctets/16; 383f9f848faSopenharmony_ci 384f9f848faSopenharmony_ci switch (cipher->mode) { 385f9f848faSopenharmony_ci case MODE_ECB: 386f9f848faSopenharmony_ci /* all blocks but last */ 387f9f848faSopenharmony_ci for (i = numBlocks - 1; i > 0; i--) { 388f9f848faSopenharmony_ci rijndaelDecrypt(key->rk, key->Nr, input, outBuffer); 389f9f848faSopenharmony_ci input += 16; 390f9f848faSopenharmony_ci outBuffer += 16; 391f9f848faSopenharmony_ci } 392f9f848faSopenharmony_ci /* last block */ 393f9f848faSopenharmony_ci rijndaelDecrypt(key->rk, key->Nr, input, block); 394f9f848faSopenharmony_ci padLen = block[15]; 395f9f848faSopenharmony_ci if (padLen >= 16) { 396f9f848faSopenharmony_ci rval = BAD_DATA; 397f9f848faSopenharmony_ci goto out; 398f9f848faSopenharmony_ci } 399f9f848faSopenharmony_ci for (i = 16 - padLen; i < 16; i++) { 400f9f848faSopenharmony_ci if (block[i] != padLen) { 401f9f848faSopenharmony_ci rval = BAD_DATA; 402f9f848faSopenharmony_ci goto out; 403f9f848faSopenharmony_ci } 404f9f848faSopenharmony_ci } 405f9f848faSopenharmony_ci memcpy(outBuffer, block, 16 - padLen); 406f9f848faSopenharmony_ci break; 407f9f848faSopenharmony_ci 408f9f848faSopenharmony_ci case MODE_CBC: 409f9f848faSopenharmony_ci memcpy(iv, cipher->IV, 16); 410f9f848faSopenharmony_ci /* all blocks but last */ 411f9f848faSopenharmony_ci for (i = numBlocks - 1; i > 0; i--) { 412f9f848faSopenharmony_ci rijndaelDecrypt(key->rk, key->Nr, input, block); 413f9f848faSopenharmony_ci ((uint32_t*)block)[0] ^= iv[0]; 414f9f848faSopenharmony_ci ((uint32_t*)block)[1] ^= iv[1]; 415f9f848faSopenharmony_ci ((uint32_t*)block)[2] ^= iv[2]; 416f9f848faSopenharmony_ci ((uint32_t*)block)[3] ^= iv[3]; 417f9f848faSopenharmony_ci memcpy(iv, input, 16); 418f9f848faSopenharmony_ci memcpy(outBuffer, block, 16); 419f9f848faSopenharmony_ci input += 16; 420f9f848faSopenharmony_ci outBuffer += 16; 421f9f848faSopenharmony_ci } 422f9f848faSopenharmony_ci /* last block */ 423f9f848faSopenharmony_ci rijndaelDecrypt(key->rk, key->Nr, input, block); 424f9f848faSopenharmony_ci ((uint32_t*)block)[0] ^= iv[0]; 425f9f848faSopenharmony_ci ((uint32_t*)block)[1] ^= iv[1]; 426f9f848faSopenharmony_ci ((uint32_t*)block)[2] ^= iv[2]; 427f9f848faSopenharmony_ci ((uint32_t*)block)[3] ^= iv[3]; 428f9f848faSopenharmony_ci padLen = block[15]; 429f9f848faSopenharmony_ci if (padLen <= 0 || padLen > 16) { 430f9f848faSopenharmony_ci rval = BAD_DATA; 431f9f848faSopenharmony_ci goto out; 432f9f848faSopenharmony_ci } 433f9f848faSopenharmony_ci for (i = 16 - padLen; i < 16; i++) { 434f9f848faSopenharmony_ci if (block[i] != padLen) { 435f9f848faSopenharmony_ci rval = BAD_DATA; 436f9f848faSopenharmony_ci goto out; 437f9f848faSopenharmony_ci } 438f9f848faSopenharmony_ci } 439f9f848faSopenharmony_ci memcpy(outBuffer, block, 16 - padLen); 440f9f848faSopenharmony_ci break; 441f9f848faSopenharmony_ci 442f9f848faSopenharmony_ci default: 443f9f848faSopenharmony_ci return BAD_CIPHER_STATE; 444f9f848faSopenharmony_ci } 445f9f848faSopenharmony_ci 446f9f848faSopenharmony_ci rval = 16*numBlocks - padLen; 447f9f848faSopenharmony_ci 448f9f848faSopenharmony_ciout: 449f9f848faSopenharmony_ci explicit_bzero(block, sizeof(block)); 450f9f848faSopenharmony_ci return rval; 451f9f848faSopenharmony_ci} 452