Annotation of sys/crypto/cast.c, Revision 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