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 243