The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/crypto/rijndael/rijndael-api-fst.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: 76cc8c01ec35dc1ccfee2a6f7ba2a7cd


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.