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$");
   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 uint8_t BYTE;
   36 
   37 int rijndael_makeKey(keyInstance *key, BYTE direction, int keyLen,
   38         const char *keyMaterial) {
   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         if (direction == DIR_ENCRYPT) {
   62                 key->Nr = rijndaelKeySetupEnc(key->rk, key->keyMaterial, keyLen);
   63         } else {
   64                 key->Nr = rijndaelKeySetupDec(key->rk, key->keyMaterial, keyLen);
   65         }
   66         rijndaelKeySetupEnc(key->ek, key->keyMaterial, keyLen);
   67         return TRUE;
   68 }
   69 
   70 int rijndael_cipherInit(cipherInstance *cipher, BYTE mode, char *IV) {
   71         if ((mode == MODE_ECB) || (mode == MODE_CBC) || (mode == MODE_CFB1)) {
   72                 cipher->mode = mode;
   73         } else {
   74                 return BAD_CIPHER_MODE;
   75         }
   76         if (IV != NULL) {
   77                 memcpy(cipher->IV, IV, RIJNDAEL_MAX_IV_SIZE);
   78         } else {
   79                 memset(cipher->IV, 0, RIJNDAEL_MAX_IV_SIZE);
   80         }
   81         return TRUE;
   82 }
   83 
   84 int rijndael_blockEncrypt(cipherInstance *cipher, keyInstance *key,
   85                 const BYTE *input, int inputLen, BYTE *outBuffer) {
   86         int i, k, numBlocks;
   87         uint8_t block[16], iv[4][4];
   88 
   89         if (cipher == NULL ||
   90                 key == NULL ||
   91                 key->direction == DIR_DECRYPT) {
   92                 return BAD_CIPHER_STATE;
   93         }
   94         if (input == NULL || inputLen <= 0) {
   95                 return 0; /* nothing to do */
   96         }
   97 
   98         numBlocks = inputLen/128;
   99 
  100         switch (cipher->mode) {
  101         case MODE_ECB:
  102                 for (i = numBlocks; i > 0; i--) {
  103                         rijndaelEncrypt(key->rk, key->Nr, input, outBuffer);
  104                         input += 16;
  105                         outBuffer += 16;
  106                 }
  107                 break;
  108 
  109         case MODE_CBC:
  110 #if 1 /*STRICT_ALIGN*/
  111                 memcpy(block, cipher->IV, 16);
  112                 memcpy(iv, input, 16);
  113                 ((uint32_t*)block)[0] ^= ((uint32_t*)iv)[0];
  114                 ((uint32_t*)block)[1] ^= ((uint32_t*)iv)[1];
  115                 ((uint32_t*)block)[2] ^= ((uint32_t*)iv)[2];
  116                 ((uint32_t*)block)[3] ^= ((uint32_t*)iv)[3];
  117 #else
  118                 ((uint32_t*)block)[0] = ((uint32_t*)cipher->IV)[0] ^ ((uint32_t*)input)[0];
  119                 ((uint32_t*)block)[1] = ((uint32_t*)cipher->IV)[1] ^ ((uint32_t*)input)[1];
  120                 ((uint32_t*)block)[2] = ((uint32_t*)cipher->IV)[2] ^ ((uint32_t*)input)[2];
  121                 ((uint32_t*)block)[3] = ((uint32_t*)cipher->IV)[3] ^ ((uint32_t*)input)[3];
  122 #endif
  123                 rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
  124                 input += 16;
  125                 for (i = numBlocks - 1; i > 0; i--) {
  126 #if 1 /*STRICT_ALIGN*/
  127                         memcpy(block, outBuffer, 16);
  128                         memcpy(iv, input, 16);
  129                         ((uint32_t*)block)[0] ^= ((uint32_t*)iv)[0];
  130                         ((uint32_t*)block)[1] ^= ((uint32_t*)iv)[1];
  131                         ((uint32_t*)block)[2] ^= ((uint32_t*)iv)[2];
  132                         ((uint32_t*)block)[3] ^= ((uint32_t*)iv)[3];
  133 #else
  134                         ((uint32_t*)block)[0] = ((uint32_t*)outBuffer)[0] ^ ((uint32_t*)input)[0];
  135                         ((uint32_t*)block)[1] = ((uint32_t*)outBuffer)[1] ^ ((uint32_t*)input)[1];
  136                         ((uint32_t*)block)[2] = ((uint32_t*)outBuffer)[2] ^ ((uint32_t*)input)[2];
  137                         ((uint32_t*)block)[3] = ((uint32_t*)outBuffer)[3] ^ ((uint32_t*)input)[3];
  138 #endif
  139                         outBuffer += 16;
  140                         rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
  141                         input += 16;
  142                 }
  143                 break;
  144 
  145         case MODE_CFB1:
  146 #if 1 /*STRICT_ALIGN*/
  147                 memcpy(iv, cipher->IV, 16);
  148 #else  /* !STRICT_ALIGN */
  149                 *((uint32_t*)iv[0]) = *((uint32_t*)(cipher->IV   ));
  150                 *((uint32_t*)iv[1]) = *((uint32_t*)(cipher->IV+ 4));
  151                 *((uint32_t*)iv[2]) = *((uint32_t*)(cipher->IV+ 8));
  152                 *((uint32_t*)iv[3]) = *((uint32_t*)(cipher->IV+12));
  153 #endif /* ?STRICT_ALIGN */
  154                 for (i = numBlocks; i > 0; i--) {
  155                         for (k = 0; k < 128; k++) {
  156                                 *((uint32_t*) block    ) = *((uint32_t*)iv[0]);
  157                                 *((uint32_t*)(block+ 4)) = *((uint32_t*)iv[1]);
  158                                 *((uint32_t*)(block+ 8)) = *((uint32_t*)iv[2]);
  159                                 *((uint32_t*)(block+12)) = *((uint32_t*)iv[3]);
  160                                 rijndaelEncrypt(key->ek, key->Nr, block,
  161                                     block);
  162                                 outBuffer[k/8] ^= (block[0] & 0x80) >> (k & 7);
  163                                 iv[0][0] = (iv[0][0] << 1) | (iv[0][1] >> 7);
  164                                 iv[0][1] = (iv[0][1] << 1) | (iv[0][2] >> 7);
  165                                 iv[0][2] = (iv[0][2] << 1) | (iv[0][3] >> 7);
  166                                 iv[0][3] = (iv[0][3] << 1) | (iv[1][0] >> 7);
  167                                 iv[1][0] = (iv[1][0] << 1) | (iv[1][1] >> 7);
  168                                 iv[1][1] = (iv[1][1] << 1) | (iv[1][2] >> 7);
  169                                 iv[1][2] = (iv[1][2] << 1) | (iv[1][3] >> 7);
  170                                 iv[1][3] = (iv[1][3] << 1) | (iv[2][0] >> 7);
  171                                 iv[2][0] = (iv[2][0] << 1) | (iv[2][1] >> 7);
  172                                 iv[2][1] = (iv[2][1] << 1) | (iv[2][2] >> 7);
  173                                 iv[2][2] = (iv[2][2] << 1) | (iv[2][3] >> 7);
  174                                 iv[2][3] = (iv[2][3] << 1) | (iv[3][0] >> 7);
  175                                 iv[3][0] = (iv[3][0] << 1) | (iv[3][1] >> 7);
  176                                 iv[3][1] = (iv[3][1] << 1) | (iv[3][2] >> 7);
  177                                 iv[3][2] = (iv[3][2] << 1) | (iv[3][3] >> 7);
  178                                 iv[3][3] = (iv[3][3] << 1) | ((outBuffer[k/8] >> (7-(k&7))) & 1);
  179                         }
  180                 }
  181                 break;
  182 
  183         default:
  184                 return BAD_CIPHER_STATE;
  185         }
  186 
  187         explicit_bzero(block, sizeof(block));
  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                 const BYTE *input, int inputOctets, BYTE *outBuffer) {
  202         int i, numBlocks, padLen;
  203         uint8_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                         ((uint32_t*)block)[0] = ((const uint32_t*)input)[0] ^ ((uint32_t*)iv)[0];
  236                         ((uint32_t*)block)[1] = ((const uint32_t*)input)[1] ^ ((uint32_t*)iv)[1];
  237                         ((uint32_t*)block)[2] = ((const uint32_t*)input)[2] ^ ((uint32_t*)iv)[2];
  238                         ((uint32_t*)block)[3] = ((const uint32_t*)input)[3] ^ ((uint32_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         explicit_bzero(block, sizeof(block));
  261         return 16*(numBlocks + 1);
  262 }
  263 
  264 int rijndael_blockDecrypt(cipherInstance *cipher, keyInstance *key,
  265                 const BYTE *input, int inputLen, BYTE *outBuffer) {
  266         int i, k, numBlocks;
  267         uint8_t block[16], iv[4][4];
  268 
  269         if (cipher == NULL ||
  270                 key == NULL ||
  271                 (cipher->mode != MODE_CFB1 && key->direction == DIR_ENCRYPT)) {
  272                 return BAD_CIPHER_STATE;
  273         }
  274         if (input == NULL || inputLen <= 0) {
  275                 return 0; /* nothing to do */
  276         }
  277 
  278         numBlocks = inputLen/128;
  279 
  280         switch (cipher->mode) {
  281         case MODE_ECB:
  282                 for (i = numBlocks; i > 0; i--) {
  283                         rijndaelDecrypt(key->rk, key->Nr, input, outBuffer);
  284                         input += 16;
  285                         outBuffer += 16;
  286                 }
  287                 break;
  288 
  289         case MODE_CBC:
  290 #if 1 /*STRICT_ALIGN */
  291                 memcpy(iv, cipher->IV, 16);
  292 #else
  293                 *((uint32_t*)iv[0]) = *((uint32_t*)(cipher->IV   ));
  294                 *((uint32_t*)iv[1]) = *((uint32_t*)(cipher->IV+ 4));
  295                 *((uint32_t*)iv[2]) = *((uint32_t*)(cipher->IV+ 8));
  296                 *((uint32_t*)iv[3]) = *((uint32_t*)(cipher->IV+12));
  297 #endif
  298                 for (i = numBlocks; i > 0; i--) {
  299                         rijndaelDecrypt(key->rk, key->Nr, input, block);
  300                         ((uint32_t*)block)[0] ^= *((uint32_t*)iv[0]);
  301                         ((uint32_t*)block)[1] ^= *((uint32_t*)iv[1]);
  302                         ((uint32_t*)block)[2] ^= *((uint32_t*)iv[2]);
  303                         ((uint32_t*)block)[3] ^= *((uint32_t*)iv[3]);
  304 #if 1 /*STRICT_ALIGN*/
  305                         memcpy(iv, input, 16);
  306                         memcpy(outBuffer, block, 16);
  307 #else
  308                         *((uint32_t*)iv[0]) = ((uint32_t*)input)[0]; ((uint32_t*)outBuffer)[0] = ((uint32_t*)block)[0];
  309                         *((uint32_t*)iv[1]) = ((uint32_t*)input)[1]; ((uint32_t*)outBuffer)[1] = ((uint32_t*)block)[1];
  310                         *((uint32_t*)iv[2]) = ((uint32_t*)input)[2]; ((uint32_t*)outBuffer)[2] = ((uint32_t*)block)[2];
  311                         *((uint32_t*)iv[3]) = ((uint32_t*)input)[3]; ((uint32_t*)outBuffer)[3] = ((uint32_t*)block)[3];
  312 #endif
  313                         input += 16;
  314                         outBuffer += 16;
  315                 }
  316                 break;
  317 
  318         case MODE_CFB1:
  319 #if 1 /*STRICT_ALIGN */
  320                 memcpy(iv, cipher->IV, 16);
  321 #else
  322                 *((uint32_t*)iv[0]) = *((uint32_t*)(cipher->IV));
  323                 *((uint32_t*)iv[1]) = *((uint32_t*)(cipher->IV+ 4));
  324                 *((uint32_t*)iv[2]) = *((uint32_t*)(cipher->IV+ 8));
  325                 *((uint32_t*)iv[3]) = *((uint32_t*)(cipher->IV+12));
  326 #endif
  327                 for (i = numBlocks; i > 0; i--) {
  328                         for (k = 0; k < 128; k++) {
  329                                 *((uint32_t*) block    ) = *((uint32_t*)iv[0]);
  330                                 *((uint32_t*)(block+ 4)) = *((uint32_t*)iv[1]);
  331                                 *((uint32_t*)(block+ 8)) = *((uint32_t*)iv[2]);
  332                                 *((uint32_t*)(block+12)) = *((uint32_t*)iv[3]);
  333                                 rijndaelEncrypt(key->ek, key->Nr, block,
  334                                     block);
  335                                 iv[0][0] = (iv[0][0] << 1) | (iv[0][1] >> 7);
  336                                 iv[0][1] = (iv[0][1] << 1) | (iv[0][2] >> 7);
  337                                 iv[0][2] = (iv[0][2] << 1) | (iv[0][3] >> 7);
  338                                 iv[0][3] = (iv[0][3] << 1) | (iv[1][0] >> 7);
  339                                 iv[1][0] = (iv[1][0] << 1) | (iv[1][1] >> 7);
  340                                 iv[1][1] = (iv[1][1] << 1) | (iv[1][2] >> 7);
  341                                 iv[1][2] = (iv[1][2] << 1) | (iv[1][3] >> 7);
  342                                 iv[1][3] = (iv[1][3] << 1) | (iv[2][0] >> 7);
  343                                 iv[2][0] = (iv[2][0] << 1) | (iv[2][1] >> 7);
  344                                 iv[2][1] = (iv[2][1] << 1) | (iv[2][2] >> 7);
  345                                 iv[2][2] = (iv[2][2] << 1) | (iv[2][3] >> 7);
  346                                 iv[2][3] = (iv[2][3] << 1) | (iv[3][0] >> 7);
  347                                 iv[3][0] = (iv[3][0] << 1) | (iv[3][1] >> 7);
  348                                 iv[3][1] = (iv[3][1] << 1) | (iv[3][2] >> 7);
  349                                 iv[3][2] = (iv[3][2] << 1) | (iv[3][3] >> 7);
  350                                 iv[3][3] = (iv[3][3] << 1) | ((input[k/8] >> (7-(k&7))) & 1);
  351                                 outBuffer[k/8] ^= (block[0] & 0x80) >> (k & 7);
  352                         }
  353                 }
  354                 break;
  355 
  356         default:
  357                 return BAD_CIPHER_STATE;
  358         }
  359 
  360         explicit_bzero(block, sizeof(block));
  361         return 128*numBlocks;
  362 }
  363 
  364 int rijndael_padDecrypt(cipherInstance *cipher, keyInstance *key,
  365                 const BYTE *input, int inputOctets, BYTE *outBuffer) {
  366         int i, numBlocks, padLen, rval;
  367         uint8_t block[16];
  368         uint32_t iv[4];
  369 
  370         if (cipher == NULL ||
  371                 key == NULL ||
  372                 key->direction == DIR_ENCRYPT) {
  373                 return BAD_CIPHER_STATE;
  374         }
  375         if (input == NULL || inputOctets <= 0) {
  376                 return 0; /* nothing to do */
  377         }
  378         if (inputOctets % 16 != 0) {
  379                 return BAD_DATA;
  380         }
  381 
  382         numBlocks = inputOctets/16;
  383 
  384         switch (cipher->mode) {
  385         case MODE_ECB:
  386                 /* all blocks but last */
  387                 for (i = numBlocks - 1; i > 0; i--) {
  388                         rijndaelDecrypt(key->rk, key->Nr, input, outBuffer);
  389                         input += 16;
  390                         outBuffer += 16;
  391                 }
  392                 /* last block */
  393                 rijndaelDecrypt(key->rk, key->Nr, input, block);
  394                 padLen = block[15];
  395                 if (padLen >= 16) {
  396                         rval = BAD_DATA;
  397                         goto out;
  398                 }
  399                 for (i = 16 - padLen; i < 16; i++) {
  400                         if (block[i] != padLen) {
  401                                 rval = BAD_DATA;
  402                                 goto out;
  403                         }
  404                 }
  405                 memcpy(outBuffer, block, 16 - padLen);
  406                 break;
  407 
  408         case MODE_CBC:
  409                 memcpy(iv, cipher->IV, 16);
  410                 /* all blocks but last */
  411                 for (i = numBlocks - 1; i > 0; i--) {
  412                         rijndaelDecrypt(key->rk, key->Nr, input, block);
  413                         ((uint32_t*)block)[0] ^= iv[0];
  414                         ((uint32_t*)block)[1] ^= iv[1];
  415                         ((uint32_t*)block)[2] ^= iv[2];
  416                         ((uint32_t*)block)[3] ^= iv[3];
  417                         memcpy(iv, input, 16);
  418                         memcpy(outBuffer, block, 16);
  419                         input += 16;
  420                         outBuffer += 16;
  421                 }
  422                 /* last block */
  423                 rijndaelDecrypt(key->rk, key->Nr, input, block);
  424                 ((uint32_t*)block)[0] ^= iv[0];
  425                 ((uint32_t*)block)[1] ^= iv[1];
  426                 ((uint32_t*)block)[2] ^= iv[2];
  427                 ((uint32_t*)block)[3] ^= iv[3];
  428                 padLen = block[15];
  429                 if (padLen <= 0 || padLen > 16) {
  430                         rval = BAD_DATA;
  431                         goto out;
  432                 }
  433                 for (i = 16 - padLen; i < 16; i++) {
  434                         if (block[i] != padLen) {
  435                                 rval = BAD_DATA;
  436                                 goto out;
  437                         }
  438                 }
  439                 memcpy(outBuffer, block, 16 - padLen);
  440                 break;
  441 
  442         default:
  443                 return BAD_CIPHER_STATE;
  444         }
  445 
  446         rval = 16*numBlocks - padLen;
  447 
  448 out:
  449         explicit_bzero(block, sizeof(block));
  450         return rval;
  451 }

Cache object: 7f01be648cff1850c0516ee9cecc98d8


[ 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.