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/opencrypto/cast.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 /*      $FreeBSD: src/sys/opencrypto/cast.c,v 1.4 2007/07/05 06:59:14 peter Exp $       */
    2 /*      $OpenBSD: cast.c,v 1.2 2000/06/06 06:49:47 deraadt Exp $       */
    3 /*-
    4  *      CAST-128 in C
    5  *      Written by Steve Reid <sreid@sea-to-sky.net>
    6  *      100% Public Domain - no warranty
    7  *      Released 1997.10.11
    8  */
    9 
   10 #include <sys/types.h>
   11 #include <opencrypto/cast.h>
   12 #include <opencrypto/castsb.h>
   13 
   14 /* Macros to access 8-bit bytes out of a 32-bit word */
   15 #define U_INT8_Ta(x) ( (u_int8_t) (x>>24) )
   16 #define U_INT8_Tb(x) ( (u_int8_t) ((x>>16)&255) )
   17 #define U_INT8_Tc(x) ( (u_int8_t) ((x>>8)&255) )
   18 #define U_INT8_Td(x) ( (u_int8_t) ((x)&255) )
   19 
   20 /* Circular left shift */
   21 #define ROL(x, n) ( ((x)<<(n)) | ((x)>>(32-(n))) )
   22 
   23 /* CAST-128 uses three different round functions */
   24 #define F1(l, r, i) \
   25         t = ROL(key->xkey[i] + r, key->xkey[i+16]); \
   26         l ^= ((cast_sbox1[U_INT8_Ta(t)] ^ cast_sbox2[U_INT8_Tb(t)]) - \
   27          cast_sbox3[U_INT8_Tc(t)]) + cast_sbox4[U_INT8_Td(t)];
   28 #define F2(l, r, i) \
   29         t = ROL(key->xkey[i] ^ r, key->xkey[i+16]); \
   30         l ^= ((cast_sbox1[U_INT8_Ta(t)] - cast_sbox2[U_INT8_Tb(t)]) + \
   31          cast_sbox3[U_INT8_Tc(t)]) ^ cast_sbox4[U_INT8_Td(t)];
   32 #define F3(l, r, i) \
   33         t = ROL(key->xkey[i] - r, key->xkey[i+16]); \
   34         l ^= ((cast_sbox1[U_INT8_Ta(t)] + cast_sbox2[U_INT8_Tb(t)]) ^ \
   35          cast_sbox3[U_INT8_Tc(t)]) - cast_sbox4[U_INT8_Td(t)];
   36 
   37 
   38 /***** Encryption Function *****/
   39 
   40 void cast_encrypt(cast_key* key, u_int8_t* inblock, u_int8_t* outblock)
   41 {
   42 u_int32_t t, l, r;
   43 
   44         /* Get inblock into l,r */
   45         l = ((u_int32_t)inblock[0] << 24) | ((u_int32_t)inblock[1] << 16) |
   46          ((u_int32_t)inblock[2] << 8) | (u_int32_t)inblock[3];
   47         r = ((u_int32_t)inblock[4] << 24) | ((u_int32_t)inblock[5] << 16) |
   48          ((u_int32_t)inblock[6] << 8) | (u_int32_t)inblock[7];
   49         /* Do the work */
   50         F1(l, r,  0);
   51         F2(r, l,  1);
   52         F3(l, r,  2);
   53         F1(r, l,  3);
   54         F2(l, r,  4);
   55         F3(r, l,  5);
   56         F1(l, r,  6);
   57         F2(r, l,  7);
   58         F3(l, r,  8);
   59         F1(r, l,  9);
   60         F2(l, r, 10);
   61         F3(r, l, 11);
   62         /* Only do full 16 rounds if key length > 80 bits */
   63         if (key->rounds > 12) {
   64                 F1(l, r, 12);
   65                 F2(r, l, 13);
   66                 F3(l, r, 14);
   67                 F1(r, l, 15);
   68         }
   69         /* Put l,r into outblock */
   70         outblock[0] = U_INT8_Ta(r);
   71         outblock[1] = U_INT8_Tb(r);
   72         outblock[2] = U_INT8_Tc(r);
   73         outblock[3] = U_INT8_Td(r);
   74         outblock[4] = U_INT8_Ta(l);
   75         outblock[5] = U_INT8_Tb(l);
   76         outblock[6] = U_INT8_Tc(l);
   77         outblock[7] = U_INT8_Td(l);
   78         /* Wipe clean */
   79         t = l = r = 0;
   80 }
   81 
   82 
   83 /***** Decryption Function *****/
   84 
   85 void cast_decrypt(cast_key* key, u_int8_t* inblock, u_int8_t* outblock)
   86 {
   87 u_int32_t t, l, r;
   88 
   89         /* Get inblock into l,r */
   90         r = ((u_int32_t)inblock[0] << 24) | ((u_int32_t)inblock[1] << 16) |
   91          ((u_int32_t)inblock[2] << 8) | (u_int32_t)inblock[3];
   92         l = ((u_int32_t)inblock[4] << 24) | ((u_int32_t)inblock[5] << 16) |
   93          ((u_int32_t)inblock[6] << 8) | (u_int32_t)inblock[7];
   94         /* Do the work */
   95         /* Only do full 16 rounds if key length > 80 bits */
   96         if (key->rounds > 12) {
   97                 F1(r, l, 15);
   98                 F3(l, r, 14);
   99                 F2(r, l, 13);
  100                 F1(l, r, 12);
  101         }
  102         F3(r, l, 11);
  103         F2(l, r, 10);
  104         F1(r, l,  9);
  105         F3(l, r,  8);
  106         F2(r, l,  7);
  107         F1(l, r,  6);
  108         F3(r, l,  5);
  109         F2(l, r,  4);
  110         F1(r, l,  3);
  111         F3(l, r,  2);
  112         F2(r, l,  1);
  113         F1(l, r,  0);
  114         /* Put l,r into outblock */
  115         outblock[0] = U_INT8_Ta(l);
  116         outblock[1] = U_INT8_Tb(l);
  117         outblock[2] = U_INT8_Tc(l);
  118         outblock[3] = U_INT8_Td(l);
  119         outblock[4] = U_INT8_Ta(r);
  120         outblock[5] = U_INT8_Tb(r);
  121         outblock[6] = U_INT8_Tc(r);
  122         outblock[7] = U_INT8_Td(r);
  123         /* Wipe clean */
  124         t = l = r = 0;
  125 }
  126 
  127 
  128 /***** Key Schedual *****/
  129 
  130 void cast_setkey(cast_key* key, u_int8_t* rawkey, int keybytes)
  131 {
  132         u_int32_t t[4] = {0, 0, 0, 0}, z[4] = {0, 0, 0, 0}, x[4];
  133         int i;
  134 
  135         /* Set number of rounds to 12 or 16, depending on key length */
  136         key->rounds = (keybytes <= 10 ? 12 : 16);
  137 
  138         /* Copy key to workspace x */
  139         for (i = 0; i < 4; i++) {
  140                 x[i] = 0;
  141                 if ((i*4+0) < keybytes) x[i] = (u_int32_t)rawkey[i*4+0] << 24;
  142                 if ((i*4+1) < keybytes) x[i] |= (u_int32_t)rawkey[i*4+1] << 16;
  143                 if ((i*4+2) < keybytes) x[i] |= (u_int32_t)rawkey[i*4+2] << 8;
  144                 if ((i*4+3) < keybytes) x[i] |= (u_int32_t)rawkey[i*4+3];
  145         }
  146         /* Generate 32 subkeys, four at a time */
  147         for (i = 0; i < 32; i+=4) {
  148                 switch (i & 4) {
  149                  case 0:
  150                         t[0] = z[0] = x[0] ^ cast_sbox5[U_INT8_Tb(x[3])] ^
  151                          cast_sbox6[U_INT8_Td(x[3])] ^ cast_sbox7[U_INT8_Ta(x[3])] ^
  152                          cast_sbox8[U_INT8_Tc(x[3])] ^ cast_sbox7[U_INT8_Ta(x[2])];
  153                         t[1] = z[1] = x[2] ^ cast_sbox5[U_INT8_Ta(z[0])] ^
  154                          cast_sbox6[U_INT8_Tc(z[0])] ^ cast_sbox7[U_INT8_Tb(z[0])] ^
  155                          cast_sbox8[U_INT8_Td(z[0])] ^ cast_sbox8[U_INT8_Tc(x[2])];
  156                         t[2] = z[2] = x[3] ^ cast_sbox5[U_INT8_Td(z[1])] ^
  157                          cast_sbox6[U_INT8_Tc(z[1])] ^ cast_sbox7[U_INT8_Tb(z[1])] ^
  158                          cast_sbox8[U_INT8_Ta(z[1])] ^ cast_sbox5[U_INT8_Tb(x[2])];
  159                         t[3] = z[3] = x[1] ^ cast_sbox5[U_INT8_Tc(z[2])] ^
  160                          cast_sbox6[U_INT8_Tb(z[2])] ^ cast_sbox7[U_INT8_Td(z[2])] ^
  161                          cast_sbox8[U_INT8_Ta(z[2])] ^ cast_sbox6[U_INT8_Td(x[2])];
  162                         break;
  163                  case 4:
  164                         t[0] = x[0] = z[2] ^ cast_sbox5[U_INT8_Tb(z[1])] ^
  165                          cast_sbox6[U_INT8_Td(z[1])] ^ cast_sbox7[U_INT8_Ta(z[1])] ^
  166                          cast_sbox8[U_INT8_Tc(z[1])] ^ cast_sbox7[U_INT8_Ta(z[0])];
  167                         t[1] = x[1] = z[0] ^ cast_sbox5[U_INT8_Ta(x[0])] ^
  168                          cast_sbox6[U_INT8_Tc(x[0])] ^ cast_sbox7[U_INT8_Tb(x[0])] ^
  169                          cast_sbox8[U_INT8_Td(x[0])] ^ cast_sbox8[U_INT8_Tc(z[0])];
  170                         t[2] = x[2] = z[1] ^ cast_sbox5[U_INT8_Td(x[1])] ^
  171                          cast_sbox6[U_INT8_Tc(x[1])] ^ cast_sbox7[U_INT8_Tb(x[1])] ^
  172                          cast_sbox8[U_INT8_Ta(x[1])] ^ cast_sbox5[U_INT8_Tb(z[0])];
  173                         t[3] = x[3] = z[3] ^ cast_sbox5[U_INT8_Tc(x[2])] ^
  174                          cast_sbox6[U_INT8_Tb(x[2])] ^ cast_sbox7[U_INT8_Td(x[2])] ^
  175                          cast_sbox8[U_INT8_Ta(x[2])] ^ cast_sbox6[U_INT8_Td(z[0])];
  176                         break;
  177                 }
  178                 switch (i & 12) {
  179                  case 0:
  180                  case 12:
  181                         key->xkey[i+0] = cast_sbox5[U_INT8_Ta(t[2])] ^ cast_sbox6[U_INT8_Tb(t[2])] ^
  182                          cast_sbox7[U_INT8_Td(t[1])] ^ cast_sbox8[U_INT8_Tc(t[1])];
  183                         key->xkey[i+1] = cast_sbox5[U_INT8_Tc(t[2])] ^ cast_sbox6[U_INT8_Td(t[2])] ^
  184                          cast_sbox7[U_INT8_Tb(t[1])] ^ cast_sbox8[U_INT8_Ta(t[1])];
  185                         key->xkey[i+2] = cast_sbox5[U_INT8_Ta(t[3])] ^ cast_sbox6[U_INT8_Tb(t[3])] ^
  186                          cast_sbox7[U_INT8_Td(t[0])] ^ cast_sbox8[U_INT8_Tc(t[0])];
  187                         key->xkey[i+3] = cast_sbox5[U_INT8_Tc(t[3])] ^ cast_sbox6[U_INT8_Td(t[3])] ^
  188                          cast_sbox7[U_INT8_Tb(t[0])] ^ cast_sbox8[U_INT8_Ta(t[0])];
  189                         break;
  190                  case 4:
  191                  case 8:
  192                         key->xkey[i+0] = cast_sbox5[U_INT8_Td(t[0])] ^ cast_sbox6[U_INT8_Tc(t[0])] ^
  193                          cast_sbox7[U_INT8_Ta(t[3])] ^ cast_sbox8[U_INT8_Tb(t[3])];
  194                         key->xkey[i+1] = cast_sbox5[U_INT8_Tb(t[0])] ^ cast_sbox6[U_INT8_Ta(t[0])] ^
  195                          cast_sbox7[U_INT8_Tc(t[3])] ^ cast_sbox8[U_INT8_Td(t[3])];
  196                         key->xkey[i+2] = cast_sbox5[U_INT8_Td(t[1])] ^ cast_sbox6[U_INT8_Tc(t[1])] ^
  197                          cast_sbox7[U_INT8_Ta(t[2])] ^ cast_sbox8[U_INT8_Tb(t[2])];
  198                         key->xkey[i+3] = cast_sbox5[U_INT8_Tb(t[1])] ^ cast_sbox6[U_INT8_Ta(t[1])] ^
  199                          cast_sbox7[U_INT8_Tc(t[2])] ^ cast_sbox8[U_INT8_Td(t[2])];
  200                         break;
  201                 }
  202                 switch (i & 12) {
  203                  case 0:
  204                         key->xkey[i+0] ^= cast_sbox5[U_INT8_Tc(z[0])];
  205                         key->xkey[i+1] ^= cast_sbox6[U_INT8_Tc(z[1])];
  206                         key->xkey[i+2] ^= cast_sbox7[U_INT8_Tb(z[2])];
  207                         key->xkey[i+3] ^= cast_sbox8[U_INT8_Ta(z[3])];
  208                         break;
  209                  case 4:
  210                         key->xkey[i+0] ^= cast_sbox5[U_INT8_Ta(x[2])];
  211                         key->xkey[i+1] ^= cast_sbox6[U_INT8_Tb(x[3])];
  212                         key->xkey[i+2] ^= cast_sbox7[U_INT8_Td(x[0])];
  213                         key->xkey[i+3] ^= cast_sbox8[U_INT8_Td(x[1])];
  214                         break;
  215                  case 8:
  216                         key->xkey[i+0] ^= cast_sbox5[U_INT8_Tb(z[2])];
  217                         key->xkey[i+1] ^= cast_sbox6[U_INT8_Ta(z[3])];
  218                         key->xkey[i+2] ^= cast_sbox7[U_INT8_Tc(z[0])];
  219                         key->xkey[i+3] ^= cast_sbox8[U_INT8_Tc(z[1])];
  220                         break;
  221                  case 12:
  222                         key->xkey[i+0] ^= cast_sbox5[U_INT8_Td(x[0])];
  223                         key->xkey[i+1] ^= cast_sbox6[U_INT8_Td(x[1])];
  224                         key->xkey[i+2] ^= cast_sbox7[U_INT8_Ta(x[2])];
  225                         key->xkey[i+3] ^= cast_sbox8[U_INT8_Tb(x[3])];
  226                         break;
  227                 }
  228                 if (i >= 16) {
  229                         key->xkey[i+0] &= 31;
  230                         key->xkey[i+1] &= 31;
  231                         key->xkey[i+2] &= 31;
  232                         key->xkey[i+3] &= 31;
  233                 }
  234         }
  235         /* Wipe clean */
  236         for (i = 0; i < 4; i++) {
  237                 t[i] = x[i] = z[i] = 0;
  238         }
  239 }
  240 
  241 /* Made in Canada */
  242 

Cache object: 1202be58050f62cb6a5fef0054802788


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