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 u_int8_t        BYTE;
   36 
   37 int rijndael_makeKey(keyInstance *key, BYTE direction, int keyLen,
   38         const char *keyMaterial) {
   39         u_int8_t cipherKey[RIJNDAEL_MAXKB];
   40 
   41         if (key == NULL) {
   42                 return BAD_KEY_INSTANCE;
   43         }
   44 
   45         if ((direction == DIR_ENCRYPT) || (direction == DIR_DECRYPT)) {
   46                 key->direction = direction;
   47         } else {
   48                 return BAD_KEY_DIR;
   49         }
   50 
   51         if ((keyLen == 128) || (keyLen == 192) || (keyLen == 256)) {
   52                 key->keyLen = keyLen;
   53         } else {
   54                 return BAD_KEY_MAT;
   55         }
   56 
   57         if (keyMaterial != NULL) {
   58                 memcpy(key->keyMaterial, keyMaterial, keyLen/8);
   59         }
   60 
   61         /* initialize key schedule: */
   62         memcpy(cipherKey, key->keyMaterial, keyLen/8);
   63         if (direction == DIR_ENCRYPT) {
   64                 key->Nr = rijndaelKeySetupEnc(key->rk, cipherKey, keyLen);
   65         } else {
   66                 key->Nr = rijndaelKeySetupDec(key->rk, cipherKey, keyLen);
   67         }
   68         rijndaelKeySetupEnc(key->ek, cipherKey, keyLen);
   69         return TRUE;
   70 }
   71 
   72 int rijndael_cipherInit(cipherInstance *cipher, BYTE mode, char *IV) {
   73         if ((mode == MODE_ECB) || (mode == MODE_CBC) || (mode == MODE_CFB1)) {
   74                 cipher->mode = mode;
   75         } else {
   76                 return BAD_CIPHER_MODE;
   77         }
   78         if (IV != NULL) {
   79                 memcpy(cipher->IV, IV, RIJNDAEL_MAX_IV_SIZE);
   80         } else {
   81                 memset(cipher->IV, 0, RIJNDAEL_MAX_IV_SIZE);
   82         }
   83         return TRUE;
   84 }
   85 
   86 int rijndael_blockEncrypt(cipherInstance *cipher, keyInstance *key,
   87                 const BYTE *input, int inputLen, BYTE *outBuffer) {
   88         int i, k, numBlocks;
   89         u_int8_t block[16], iv[4][4];
   90 
   91         if (cipher == NULL ||
   92                 key == NULL ||
   93                 key->direction == DIR_DECRYPT) {
   94                 return BAD_CIPHER_STATE;
   95         }
   96         if (input == NULL || inputLen <= 0) {
   97                 return 0; /* nothing to do */
   98         }
   99 
  100         numBlocks = inputLen/128;
  101 
  102         switch (cipher->mode) {
  103         case MODE_ECB:
  104                 for (i = numBlocks; i > 0; i--) {
  105                         rijndaelEncrypt(key->rk, key->Nr, input, outBuffer);
  106                         input += 16;
  107                         outBuffer += 16;
  108                 }
  109                 break;
  110 
  111         case MODE_CBC:
  112 #if 1 /*STRICT_ALIGN*/
  113                 memcpy(block, cipher->IV, 16);
  114                 memcpy(iv, input, 16);
  115                 ((u_int32_t*)block)[0] ^= ((u_int32_t*)iv)[0];
  116                 ((u_int32_t*)block)[1] ^= ((u_int32_t*)iv)[1];
  117                 ((u_int32_t*)block)[2] ^= ((u_int32_t*)iv)[2];
  118                 ((u_int32_t*)block)[3] ^= ((u_int32_t*)iv)[3];
  119 #else
  120                 ((u_int32_t*)block)[0] = ((u_int32_t*)cipher->IV)[0] ^ ((u_int32_t*)input)[0];
  121                 ((u_int32_t*)block)[1] = ((u_int32_t*)cipher->IV)[1] ^ ((u_int32_t*)input)[1];
  122                 ((u_int32_t*)block)[2] = ((u_int32_t*)cipher->IV)[2] ^ ((u_int32_t*)input)[2];
  123                 ((u_int32_t*)block)[3] = ((u_int32_t*)cipher->IV)[3] ^ ((u_int32_t*)input)[3];
  124 #endif
  125                 rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
  126                 input += 16;
  127                 for (i = numBlocks - 1; i > 0; i--) {
  128 #if 1 /*STRICT_ALIGN*/
  129                         memcpy(block, outBuffer, 16);
  130                         memcpy(iv, input, 16);
  131                         ((u_int32_t*)block)[0] ^= ((u_int32_t*)iv)[0];
  132                         ((u_int32_t*)block)[1] ^= ((u_int32_t*)iv)[1];
  133                         ((u_int32_t*)block)[2] ^= ((u_int32_t*)iv)[2];
  134                         ((u_int32_t*)block)[3] ^= ((u_int32_t*)iv)[3];
  135 #else
  136                         ((u_int32_t*)block)[0] = ((u_int32_t*)outBuffer)[0] ^ ((u_int32_t*)input)[0];
  137                         ((u_int32_t*)block)[1] = ((u_int32_t*)outBuffer)[1] ^ ((u_int32_t*)input)[1];
  138                         ((u_int32_t*)block)[2] = ((u_int32_t*)outBuffer)[2] ^ ((u_int32_t*)input)[2];
  139                         ((u_int32_t*)block)[3] = ((u_int32_t*)outBuffer)[3] ^ ((u_int32_t*)input)[3];
  140 #endif
  141                         outBuffer += 16;
  142                         rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
  143                         input += 16;
  144                 }
  145                 break;
  146 
  147         case MODE_CFB1:
  148 #if 1 /*STRICT_ALIGN*/
  149                 memcpy(iv, cipher->IV, 16);
  150 #else  /* !STRICT_ALIGN */
  151                 *((u_int32_t*)iv[0]) = *((u_int32_t*)(cipher->IV   ));
  152                 *((u_int32_t*)iv[1]) = *((u_int32_t*)(cipher->IV+ 4));
  153                 *((u_int32_t*)iv[2]) = *((u_int32_t*)(cipher->IV+ 8));
  154                 *((u_int32_t*)iv[3]) = *((u_int32_t*)(cipher->IV+12));
  155 #endif /* ?STRICT_ALIGN */
  156                 for (i = numBlocks; i > 0; i--) {
  157                         for (k = 0; k < 128; k++) {
  158                                 *((u_int32_t*) block    ) = *((u_int32_t*)iv[0]);
  159                                 *((u_int32_t*)(block+ 4)) = *((u_int32_t*)iv[1]);
  160                                 *((u_int32_t*)(block+ 8)) = *((u_int32_t*)iv[2]);
  161                                 *((u_int32_t*)(block+12)) = *((u_int32_t*)iv[3]);
  162                                 rijndaelEncrypt(key->ek, key->Nr, block,
  163                                     block);
  164                                 outBuffer[k/8] ^= (block[0] & 0x80) >> (k & 7);
  165                                 iv[0][0] = (iv[0][0] << 1) | (iv[0][1] >> 7);
  166                                 iv[0][1] = (iv[0][1] << 1) | (iv[0][2] >> 7);
  167                                 iv[0][2] = (iv[0][2] << 1) | (iv[0][3] >> 7);
  168                                 iv[0][3] = (iv[0][3] << 1) | (iv[1][0] >> 7);
  169                                 iv[1][0] = (iv[1][0] << 1) | (iv[1][1] >> 7);
  170                                 iv[1][1] = (iv[1][1] << 1) | (iv[1][2] >> 7);
  171                                 iv[1][2] = (iv[1][2] << 1) | (iv[1][3] >> 7);
  172                                 iv[1][3] = (iv[1][3] << 1) | (iv[2][0] >> 7);
  173                                 iv[2][0] = (iv[2][0] << 1) | (iv[2][1] >> 7);
  174                                 iv[2][1] = (iv[2][1] << 1) | (iv[2][2] >> 7);
  175                                 iv[2][2] = (iv[2][2] << 1) | (iv[2][3] >> 7);
  176                                 iv[2][3] = (iv[2][3] << 1) | (iv[3][0] >> 7);
  177                                 iv[3][0] = (iv[3][0] << 1) | (iv[3][1] >> 7);
  178                                 iv[3][1] = (iv[3][1] << 1) | (iv[3][2] >> 7);
  179                                 iv[3][2] = (iv[3][2] << 1) | (iv[3][3] >> 7);
  180                                 iv[3][3] = (iv[3][3] << 1) | ((outBuffer[k/8] >> (7-(k&7))) & 1);
  181                         }
  182                 }
  183                 break;
  184 
  185         default:
  186                 return BAD_CIPHER_STATE;
  187         }
  188 
  189         return 128*numBlocks;
  190 }
  191 
  192 /**
  193  * Encrypt data partitioned in octets, using RFC 2040-like padding.
  194  *
  195  * @param   input           data to be encrypted (octet sequence)
  196  * @param   inputOctets         input length in octets (not bits)
  197  * @param   outBuffer       encrypted output data
  198  *
  199  * @return      length in octets (not bits) of the encrypted output buffer.
  200  */
  201 int rijndael_padEncrypt(cipherInstance *cipher, keyInstance *key,
  202                 const BYTE *input, int inputOctets, BYTE *outBuffer) {
  203         int i, numBlocks, padLen;
  204         u_int8_t block[16], *iv, *cp;
  205 
  206         if (cipher == NULL ||
  207                 key == NULL ||
  208                 key->direction == DIR_DECRYPT) {
  209                 return BAD_CIPHER_STATE;
  210         }
  211         if (input == NULL || inputOctets <= 0) {
  212                 return 0; /* nothing to do */
  213         }
  214 
  215         numBlocks = inputOctets/16;
  216 
  217         switch (cipher->mode) {
  218         case MODE_ECB:
  219                 for (i = numBlocks; i > 0; i--) {
  220                         rijndaelEncrypt(key->rk, key->Nr, input, outBuffer);
  221                         input += 16;
  222                         outBuffer += 16;
  223                 }
  224                 padLen = 16 - (inputOctets - 16*numBlocks);
  225                 if (padLen <= 0 || padLen > 16)
  226                         return BAD_CIPHER_STATE;
  227                 memcpy(block, input, 16 - padLen);
  228                 for (cp = block + 16 - padLen; cp < block + 16; cp++)
  229                         *cp = padLen;
  230                 rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
  231                 break;
  232 
  233         case MODE_CBC:
  234                 iv = cipher->IV;
  235                 for (i = numBlocks; i > 0; i--) {
  236                         ((u_int32_t*)block)[0] = ((const u_int32_t*)input)[0] ^ ((u_int32_t*)iv)[0];
  237                         ((u_int32_t*)block)[1] = ((const u_int32_t*)input)[1] ^ ((u_int32_t*)iv)[1];
  238                         ((u_int32_t*)block)[2] = ((const u_int32_t*)input)[2] ^ ((u_int32_t*)iv)[2];
  239                         ((u_int32_t*)block)[3] = ((const u_int32_t*)input)[3] ^ ((u_int32_t*)iv)[3];
  240                         rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
  241                         iv = outBuffer;
  242                         input += 16;
  243                         outBuffer += 16;
  244                 }
  245                 padLen = 16 - (inputOctets - 16*numBlocks);
  246                 if (padLen <= 0 || padLen > 16)
  247                         return BAD_CIPHER_STATE;
  248                 for (i = 0; i < 16 - padLen; i++) {
  249                         block[i] = input[i] ^ iv[i];
  250                 }
  251                 for (i = 16 - padLen; i < 16; i++) {
  252                         block[i] = (BYTE)padLen ^ iv[i];
  253                 }
  254                 rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
  255                 break;
  256 
  257         default:
  258                 return BAD_CIPHER_STATE;
  259         }
  260 
  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         u_int8_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                 *((u_int32_t*)iv[0]) = *((u_int32_t*)(cipher->IV   ));
  294                 *((u_int32_t*)iv[1]) = *((u_int32_t*)(cipher->IV+ 4));
  295                 *((u_int32_t*)iv[2]) = *((u_int32_t*)(cipher->IV+ 8));
  296                 *((u_int32_t*)iv[3]) = *((u_int32_t*)(cipher->IV+12));
  297 #endif
  298                 for (i = numBlocks; i > 0; i--) {
  299                         rijndaelDecrypt(key->rk, key->Nr, input, block);
  300                         ((u_int32_t*)block)[0] ^= *((u_int32_t*)iv[0]);
  301                         ((u_int32_t*)block)[1] ^= *((u_int32_t*)iv[1]);
  302                         ((u_int32_t*)block)[2] ^= *((u_int32_t*)iv[2]);
  303                         ((u_int32_t*)block)[3] ^= *((u_int32_t*)iv[3]);
  304 #if 1 /*STRICT_ALIGN*/
  305                         memcpy(iv, input, 16);
  306                         memcpy(outBuffer, block, 16);
  307 #else
  308                         *((u_int32_t*)iv[0]) = ((u_int32_t*)input)[0]; ((u_int32_t*)outBuffer)[0] = ((u_int32_t*)block)[0];
  309                         *((u_int32_t*)iv[1]) = ((u_int32_t*)input)[1]; ((u_int32_t*)outBuffer)[1] = ((u_int32_t*)block)[1];
  310                         *((u_int32_t*)iv[2]) = ((u_int32_t*)input)[2]; ((u_int32_t*)outBuffer)[2] = ((u_int32_t*)block)[2];
  311                         *((u_int32_t*)iv[3]) = ((u_int32_t*)input)[3]; ((u_int32_t*)outBuffer)[3] = ((u_int32_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                 *((u_int32_t*)iv[0]) = *((u_int32_t*)(cipher->IV));
  323                 *((u_int32_t*)iv[1]) = *((u_int32_t*)(cipher->IV+ 4));
  324                 *((u_int32_t*)iv[2]) = *((u_int32_t*)(cipher->IV+ 8));
  325                 *((u_int32_t*)iv[3]) = *((u_int32_t*)(cipher->IV+12));
  326 #endif
  327                 for (i = numBlocks; i > 0; i--) {
  328                         for (k = 0; k < 128; k++) {
  329                                 *((u_int32_t*) block    ) = *((u_int32_t*)iv[0]);
  330                                 *((u_int32_t*)(block+ 4)) = *((u_int32_t*)iv[1]);
  331                                 *((u_int32_t*)(block+ 8)) = *((u_int32_t*)iv[2]);
  332                                 *((u_int32_t*)(block+12)) = *((u_int32_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         return 128*numBlocks;
  361 }
  362 
  363 int rijndael_padDecrypt(cipherInstance *cipher, keyInstance *key,
  364                 const BYTE *input, int inputOctets, BYTE *outBuffer) {
  365         int i, numBlocks, padLen;
  366         u_int8_t block[16];
  367         u_int32_t iv[4];
  368 
  369         if (cipher == NULL ||
  370                 key == NULL ||
  371                 key->direction == DIR_ENCRYPT) {
  372                 return BAD_CIPHER_STATE;
  373         }
  374         if (input == NULL || inputOctets <= 0) {
  375                 return 0; /* nothing to do */
  376         }
  377         if (inputOctets % 16 != 0) {
  378                 return BAD_DATA;
  379         }
  380 
  381         numBlocks = inputOctets/16;
  382 
  383         switch (cipher->mode) {
  384         case MODE_ECB:
  385                 /* all blocks but last */
  386                 for (i = numBlocks - 1; i > 0; i--) {
  387                         rijndaelDecrypt(key->rk, key->Nr, input, outBuffer);
  388                         input += 16;
  389                         outBuffer += 16;
  390                 }
  391                 /* last block */
  392                 rijndaelDecrypt(key->rk, key->Nr, input, block);
  393                 padLen = block[15];
  394                 if (padLen >= 16) {
  395                         return BAD_DATA;
  396                 }
  397                 for (i = 16 - padLen; i < 16; i++) {
  398                         if (block[i] != padLen) {
  399                                 return BAD_DATA;
  400                         }
  401                 }
  402                 memcpy(outBuffer, block, 16 - padLen);
  403                 break;
  404 
  405         case MODE_CBC:
  406                 memcpy(iv, cipher->IV, 16);
  407                 /* all blocks but last */
  408                 for (i = numBlocks - 1; i > 0; i--) {
  409                         rijndaelDecrypt(key->rk, key->Nr, input, block);
  410                         ((u_int32_t*)block)[0] ^= iv[0];
  411                         ((u_int32_t*)block)[1] ^= iv[1];
  412                         ((u_int32_t*)block)[2] ^= iv[2];
  413                         ((u_int32_t*)block)[3] ^= iv[3];
  414                         memcpy(iv, input, 16);
  415                         memcpy(outBuffer, block, 16);
  416                         input += 16;
  417                         outBuffer += 16;
  418                 }
  419                 /* last block */
  420                 rijndaelDecrypt(key->rk, key->Nr, input, block);
  421                 ((u_int32_t*)block)[0] ^= iv[0];
  422                 ((u_int32_t*)block)[1] ^= iv[1];
  423                 ((u_int32_t*)block)[2] ^= iv[2];
  424                 ((u_int32_t*)block)[3] ^= iv[3];
  425                 padLen = block[15];
  426                 if (padLen <= 0 || padLen > 16) {
  427                         return BAD_DATA;
  428                 }
  429                 for (i = 16 - padLen; i < 16; i++) {
  430                         if (block[i] != padLen) {
  431                                 return BAD_DATA;
  432                         }
  433                 }
  434                 memcpy(outBuffer, block, 16 - padLen);
  435                 break;
  436 
  437         default:
  438                 return BAD_CIPHER_STATE;
  439         }
  440 
  441         return 16*numBlocks - padLen;
  442 }

Cache object: ac99999a4b166e6acaa4a99fd56fd596


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