[BACK]Return to cast.c CVS log [TXT][DIR] Up to [local] / sys / crypto

Annotation of sys/crypto/cast.c, Revision 1.1.1.1

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

CVSweb