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

Cache object: 5e1aa1c07e8838fa919ddacefaec178d


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