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 /*      $NetBSD: rijndael-api-fst.c,v 1.19 2005/12/11 12:20:52 christos Exp $   */
    2 
    3 /**
    4  * rijndael-api-fst.c
    5  *
    6  * @version 2.9 (December 2000)
    7  *
    8  * Optimised ANSI C code for the Rijndael cipher (now AES)
    9  *
   10  * @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
   11  * @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
   12  * @author Paulo Barreto <paulo.barreto@terra.com.br>
   13  *
   14  * This code is hereby placed in the public domain.
   15  *
   16  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
   17  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
   18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
   20  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
   23  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
   24  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
   25  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
   26  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   27  *
   28  * Acknowledgements:
   29  *
   30  * We are deeply indebted to the following people for their bug reports,
   31  * fixes, and improvement suggestions to this implementation. Though we
   32  * tried to list all contributions, we apologise in advance for any
   33  * missing reference.
   34  *
   35  * Andrew Bales <Andrew.Bales@Honeywell.com>
   36  * Markus Friedl <markus.friedl@informatik.uni-erlangen.de>
   37  * John Skodon <skodonj@webquill.com>
   38  */
   39 
   40 #include <sys/cdefs.h>
   41 __KERNEL_RCSID(0, "$NetBSD: rijndael-api-fst.c,v 1.19 2005/12/11 12:20:52 christos Exp $");
   42 
   43 #include <sys/param.h>
   44 #ifdef _KERNEL
   45 #include <sys/systm.h>
   46 #else
   47 #include <stdlib.h>
   48 #include <string.h>
   49 #endif
   50 
   51 #include <crypto/rijndael/rijndael_local.h>
   52 #include <crypto/rijndael/rijndael-alg-fst.h>
   53 #include <crypto/rijndael/rijndael-api-fst.h>
   54 
   55 int rijndael_makeKey(keyInstance *key, BYTE direction, int keyLen, char *keyMaterial) {
   56         u_int8_t cipherKey[RIJNDAEL_MAXKB];
   57 
   58         if (key == NULL) {
   59                 return BAD_KEY_INSTANCE;
   60         }
   61 
   62         if ((direction == DIR_ENCRYPT) || (direction == DIR_DECRYPT)) {
   63                 key->direction = direction;
   64         } else {
   65                 return BAD_KEY_DIR;
   66         }
   67 
   68         if ((keyLen == 128) || (keyLen == 192) || (keyLen == 256)) {
   69                 key->keyLen = keyLen;
   70         } else {
   71                 return BAD_KEY_MAT;
   72         }
   73 
   74         if (keyMaterial != NULL) {
   75                 memcpy(key->keyMaterial, keyMaterial, keyLen/8);
   76         }
   77 
   78         /* initialize key schedule: */
   79         memcpy(cipherKey, key->keyMaterial, keyLen/8);
   80         if (direction == DIR_ENCRYPT) {
   81                 key->Nr = rijndaelKeySetupEnc(key->rk, cipherKey, keyLen);
   82         } else {
   83                 key->Nr = rijndaelKeySetupDec(key->rk, cipherKey, keyLen);
   84         }
   85         rijndaelKeySetupEnc(key->ek, cipherKey, keyLen);
   86         return TRUE;
   87 }
   88 
   89 int rijndael_cipherInit(cipherInstance *cipher, BYTE mode, char *IV) {
   90         if ((mode == MODE_ECB) || (mode == MODE_CBC) || (mode == MODE_CFB1)) {
   91                 cipher->mode = mode;
   92         } else {
   93                 return BAD_CIPHER_MODE;
   94         }
   95         if (IV != NULL) {
   96                 memcpy(cipher->IV, IV, RIJNDAEL_MAX_IV_SIZE);
   97         } else {
   98                 memset(cipher->IV, 0, RIJNDAEL_MAX_IV_SIZE);
   99         }
  100         return TRUE;
  101 }
  102 
  103 int rijndael_blockEncrypt(cipherInstance *cipher, keyInstance *key,
  104                 BYTE *input, int inputLen, BYTE *outBuffer) {
  105         int i, k, t, numBlocks;
  106         u_int8_t block[16], *iv;
  107 
  108         if (cipher == NULL ||
  109                 key == NULL ||
  110                 key->direction == DIR_DECRYPT) {
  111                 return BAD_CIPHER_STATE;
  112         }
  113         if (input == NULL || inputLen <= 0) {
  114                 return 0; /* nothing to do */
  115         }
  116 
  117         numBlocks = inputLen/128;
  118 
  119         switch (cipher->mode) {
  120         case MODE_ECB:
  121                 for (i = numBlocks; i > 0; i--) {
  122                         rijndaelEncrypt(key->rk, key->Nr, input, outBuffer);
  123                         input += 16;
  124                         outBuffer += 16;
  125                 }
  126                 break;
  127 
  128         case MODE_CBC:
  129                 iv = (u_int8_t *)cipher->IV;
  130                 for (i = numBlocks; i > 0; i--) {
  131                         ((u_int32_t*)block)[0] = ((u_int32_t*)input)[0] ^ ((u_int32_t*)iv)[0];
  132                         ((u_int32_t*)block)[1] = ((u_int32_t*)input)[1] ^ ((u_int32_t*)iv)[1];
  133                         ((u_int32_t*)block)[2] = ((u_int32_t*)input)[2] ^ ((u_int32_t*)iv)[2];
  134                         ((u_int32_t*)block)[3] = ((u_int32_t*)input)[3] ^ ((u_int32_t*)iv)[3];
  135                         rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
  136                         iv = outBuffer;
  137                         input += 16;
  138                         outBuffer += 16;
  139                 }
  140                 break;
  141 
  142     case MODE_CFB1:
  143                 iv = (u_int8_t *)cipher->IV;
  144         for (i = numBlocks; i > 0; i--) {
  145                         memcpy(outBuffer, input, 16);
  146             for (k = 0; k < 128; k++) {
  147                                 rijndaelEncrypt(key->ek, key->Nr, iv, block);
  148                 outBuffer[k >> 3] ^= (block[0] & 0x80U) >> (k & 7);
  149                 for (t = 0; t < 15; t++) {
  150                         iv[t] = (iv[t] << 1) | (iv[t + 1] >> 7);
  151                 }
  152                 iv[15] = (iv[15] << 1) | ((outBuffer[k >> 3] >> (7 - (k & 7))) & 1);
  153             }
  154             outBuffer += 16;
  155             input += 16;
  156         }
  157         break;
  158 
  159         default:
  160                 return BAD_CIPHER_STATE;
  161         }
  162 
  163         return 128*numBlocks;
  164 }
  165 
  166 /**
  167  * Encrypt data partitioned in octets, using RFC 2040-like padding.
  168  *
  169  * @param   input           data to be encrypted (octet sequence)
  170  * @param   inputOctets         input length in octets (not bits)
  171  * @param   outBuffer       encrypted output data
  172  *
  173  * @return      length in octets (not bits) of the encrypted output buffer.
  174  */
  175 int rijndael_padEncrypt(cipherInstance *cipher, keyInstance *key,
  176                 BYTE *input, int inputOctets, BYTE *outBuffer) {
  177         int i, numBlocks, padLen;
  178         u_int8_t block[16], *iv;
  179 
  180         if (cipher == NULL ||
  181                 key == NULL ||
  182                 key->direction == DIR_DECRYPT) {
  183                 return BAD_CIPHER_STATE;
  184         }
  185         if (input == NULL || inputOctets <= 0) {
  186                 return 0; /* nothing to do */
  187         }
  188 
  189         numBlocks = inputOctets/16;
  190 
  191         switch (cipher->mode) {
  192         case MODE_ECB:
  193                 for (i = numBlocks; i > 0; i--) {
  194                         rijndaelEncrypt(key->rk, key->Nr, input, outBuffer);
  195                         input += 16;
  196                         outBuffer += 16;
  197                 }
  198                 padLen = 16 - (inputOctets - 16*numBlocks);
  199                 memcpy(block, input, 16 - padLen);
  200                 memset(block + 16 - padLen, padLen, padLen);
  201                 rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
  202                 break;
  203 
  204         case MODE_CBC:
  205                 iv = (u_int8_t *)cipher->IV;
  206                 for (i = numBlocks; i > 0; i--) {
  207                         ((u_int32_t*)block)[0] = ((u_int32_t*)input)[0] ^ ((u_int32_t*)iv)[0];
  208                         ((u_int32_t*)block)[1] = ((u_int32_t*)input)[1] ^ ((u_int32_t*)iv)[1];
  209                         ((u_int32_t*)block)[2] = ((u_int32_t*)input)[2] ^ ((u_int32_t*)iv)[2];
  210                         ((u_int32_t*)block)[3] = ((u_int32_t*)input)[3] ^ ((u_int32_t*)iv)[3];
  211                         rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
  212                         iv = outBuffer;
  213                         input += 16;
  214                         outBuffer += 16;
  215                 }
  216                 padLen = 16 - (inputOctets - 16*numBlocks);
  217                 for (i = 0; i < 16 - padLen; i++) {
  218                         block[i] = input[i] ^ iv[i];
  219                 }
  220                 for (i = 16 - padLen; i < 16; i++) {
  221                         block[i] = (BYTE)padLen ^ iv[i];
  222                 }
  223                 rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
  224                 break;
  225 
  226         default:
  227                 return BAD_CIPHER_STATE;
  228         }
  229 
  230         return 16*(numBlocks + 1);
  231 }
  232 
  233 int rijndael_blockDecrypt(cipherInstance *cipher, keyInstance *key,
  234                 BYTE *input, int inputLen, BYTE *outBuffer) {
  235         int i, k, t, numBlocks;
  236         u_int8_t block[16], *iv;
  237 
  238         if (cipher == NULL ||
  239                 key == NULL ||
  240                 (cipher->mode != MODE_CFB1 && key->direction == DIR_ENCRYPT)) {
  241                 return BAD_CIPHER_STATE;
  242         }
  243         if (input == NULL || inputLen <= 0) {
  244                 return 0; /* nothing to do */
  245         }
  246 
  247         numBlocks = inputLen/128;
  248 
  249         switch (cipher->mode) {
  250         case MODE_ECB:
  251                 for (i = numBlocks; i > 0; i--) {
  252                         rijndaelDecrypt(key->rk, key->Nr, input, outBuffer);
  253                         input += 16;
  254                         outBuffer += 16;
  255                 }
  256                 break;
  257 
  258         case MODE_CBC:
  259                 iv = (u_int8_t *)cipher->IV;
  260                 for (i = numBlocks; i > 0; i--) {
  261                         rijndaelDecrypt(key->rk, key->Nr, input, block);
  262                         ((u_int32_t*)block)[0] ^= ((u_int32_t*)iv)[0];
  263                         ((u_int32_t*)block)[1] ^= ((u_int32_t*)iv)[1];
  264                         ((u_int32_t*)block)[2] ^= ((u_int32_t*)iv)[2];
  265                         ((u_int32_t*)block)[3] ^= ((u_int32_t*)iv)[3];
  266                         memcpy(cipher->IV, input, 16);
  267                         memcpy(outBuffer, block, 16);
  268                         input += 16;
  269                         outBuffer += 16;
  270                 }
  271                 break;
  272 
  273     case MODE_CFB1:
  274                 iv = (u_int8_t *)cipher->IV;
  275         for (i = numBlocks; i > 0; i--) {
  276                         memcpy(outBuffer, input, 16);
  277             for (k = 0; k < 128; k++) {
  278                                 rijndaelEncrypt(key->ek, key->Nr, iv, block);
  279                 for (t = 0; t < 15; t++) {
  280                         iv[t] = (iv[t] << 1) | (iv[t + 1] >> 7);
  281                 }
  282                 iv[15] = (iv[15] << 1) | ((input[k >> 3] >> (7 - (k & 7))) & 1);
  283                 outBuffer[k >> 3] ^= (block[0] & 0x80U) >> (k & 7);
  284             }
  285             outBuffer += 16;
  286             input += 16;
  287         }
  288         break;
  289 
  290         default:
  291                 return BAD_CIPHER_STATE;
  292         }
  293 
  294         return 128*numBlocks;
  295 }
  296 
  297 int rijndael_padDecrypt(cipherInstance *cipher, keyInstance *key,
  298                 BYTE *input, int inputOctets, BYTE *outBuffer) {
  299         int i, numBlocks, padLen;
  300         u_int8_t block[16];
  301 
  302         if (cipher == NULL ||
  303                 key == NULL ||
  304                 key->direction == DIR_ENCRYPT) {
  305                 return BAD_CIPHER_STATE;
  306         }
  307         if (input == NULL || inputOctets <= 0) {
  308                 return 0; /* nothing to do */
  309         }
  310         if (inputOctets % 16 != 0) {
  311                 return BAD_DATA;
  312         }
  313 
  314         numBlocks = inputOctets/16;
  315 
  316         switch (cipher->mode) {
  317         case MODE_ECB:
  318                 /* all blocks but last */
  319                 for (i = numBlocks - 1; i > 0; i--) {
  320                         rijndaelDecrypt(key->rk, key->Nr, input, outBuffer);
  321                         input += 16;
  322                         outBuffer += 16;
  323                 }
  324                 /* last block */
  325                 rijndaelDecrypt(key->rk, key->Nr, input, block);
  326                 padLen = block[15];
  327                 if (padLen >= 16) {
  328                         return BAD_DATA;
  329                 }
  330                 for (i = 16 - padLen; i < 16; i++) {
  331                         if (block[i] != padLen) {
  332                                 return BAD_DATA;
  333                         }
  334                 }
  335                 memcpy(outBuffer, block, 16 - padLen);
  336                 break;
  337 
  338         case MODE_CBC:
  339                 /* all blocks but last */
  340                 for (i = numBlocks - 1; i > 0; i--) {
  341                         rijndaelDecrypt(key->rk, key->Nr, input, block);
  342                         ((u_int32_t*)block)[0] ^= ((u_int32_t*)cipher->IV)[0];
  343                         ((u_int32_t*)block)[1] ^= ((u_int32_t*)cipher->IV)[1];
  344                         ((u_int32_t*)block)[2] ^= ((u_int32_t*)cipher->IV)[2];
  345                         ((u_int32_t*)block)[3] ^= ((u_int32_t*)cipher->IV)[3];
  346                         memcpy(cipher->IV, input, 16);
  347                         memcpy(outBuffer, block, 16);
  348                         input += 16;
  349                         outBuffer += 16;
  350                 }
  351                 /* last block */
  352                 rijndaelDecrypt(key->rk, key->Nr, input, block);
  353                 ((u_int32_t*)block)[0] ^= ((u_int32_t*)cipher->IV)[0];
  354                 ((u_int32_t*)block)[1] ^= ((u_int32_t*)cipher->IV)[1];
  355                 ((u_int32_t*)block)[2] ^= ((u_int32_t*)cipher->IV)[2];
  356                 ((u_int32_t*)block)[3] ^= ((u_int32_t*)cipher->IV)[3];
  357                 padLen = block[15];
  358                 if (padLen <= 0 || padLen > 16) {
  359                         return BAD_DATA;
  360                 }
  361                 for (i = 16 - padLen; i < 16; i++) {
  362                         if (block[i] != padLen) {
  363                                 return BAD_DATA;
  364                         }
  365                 }
  366                 memcpy(outBuffer, block, 16 - padLen);
  367                 break;
  368 
  369         default:
  370                 return BAD_CIPHER_STATE;
  371         }
  372 
  373         return 16*numBlocks - padLen;
  374 }
  375 

Cache object: b3a33507a640aec33a338637a49a3c06


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