1 /* $FreeBSD: src/sys/opencrypto/cast.c,v 1.1.2.1 2002/11/21 23:34:23 sam Exp $ */ 2 /* $OpenBSD: cast.c,v 1.2 2000/06/06 06:49:47 deraadt Exp $ */ 3 4 /* 5 * CAST-128 in C 6 * Written by Steve Reid <sreid@sea-to-sky.net> 7 * 100% Public Domain - no warranty 8 * Released 1997.10.11 9 */ 10 11 #include <sys/types.h> 12 #include <opencrypto/cast.h> 13 #include <opencrypto/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 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 cast_decrypt(cast_key* key, u_int8_t* inblock, u_int8_t* outblock) 87 { 88 u_int32_t t, l, r; 89 90 /* Get inblock into l,r */ 91 r = ((u_int32_t)inblock[0] << 24) | ((u_int32_t)inblock[1] << 16) | 92 ((u_int32_t)inblock[2] << 8) | (u_int32_t)inblock[3]; 93 l = ((u_int32_t)inblock[4] << 24) | ((u_int32_t)inblock[5] << 16) | 94 ((u_int32_t)inblock[6] << 8) | (u_int32_t)inblock[7]; 95 /* Do the work */ 96 /* Only do full 16 rounds if key length > 80 bits */ 97 if (key->rounds > 12) { 98 F1(r, l, 15); 99 F3(l, r, 14); 100 F2(r, l, 13); 101 F1(l, r, 12); 102 } 103 F3(r, l, 11); 104 F2(l, r, 10); 105 F1(r, l, 9); 106 F3(l, r, 8); 107 F2(r, l, 7); 108 F1(l, r, 6); 109 F3(r, l, 5); 110 F2(l, r, 4); 111 F1(r, l, 3); 112 F3(l, r, 2); 113 F2(r, l, 1); 114 F1(l, r, 0); 115 /* Put l,r into outblock */ 116 outblock[0] = U_INT8_Ta(l); 117 outblock[1] = U_INT8_Tb(l); 118 outblock[2] = U_INT8_Tc(l); 119 outblock[3] = U_INT8_Td(l); 120 outblock[4] = U_INT8_Ta(r); 121 outblock[5] = U_INT8_Tb(r); 122 outblock[6] = U_INT8_Tc(r); 123 outblock[7] = U_INT8_Td(r); 124 /* Wipe clean */ 125 t = l = r = 0; 126 } 127 128 129 /***** Key Schedual *****/ 130 131 void cast_setkey(cast_key* key, u_int8_t* rawkey, int keybytes) 132 { 133 u_int32_t t[4], z[4], x[4]; 134 int i; 135 136 /* Set number of rounds to 12 or 16, depending on key length */ 137 key->rounds = (keybytes <= 10 ? 12 : 16); 138 139 /* Copy key to workspace x */ 140 for (i = 0; i < 4; i++) { 141 x[i] = 0; 142 if ((i*4+0) < keybytes) x[i] = (u_int32_t)rawkey[i*4+0] << 24; 143 if ((i*4+1) < keybytes) x[i] |= (u_int32_t)rawkey[i*4+1] << 16; 144 if ((i*4+2) < keybytes) x[i] |= (u_int32_t)rawkey[i*4+2] << 8; 145 if ((i*4+3) < keybytes) x[i] |= (u_int32_t)rawkey[i*4+3]; 146 } 147 /* Generate 32 subkeys, four at a time */ 148 for (i = 0; i < 32; i+=4) { 149 switch (i & 4) { 150 case 0: 151 t[0] = z[0] = x[0] ^ cast_sbox5[U_INT8_Tb(x[3])] ^ 152 cast_sbox6[U_INT8_Td(x[3])] ^ cast_sbox7[U_INT8_Ta(x[3])] ^ 153 cast_sbox8[U_INT8_Tc(x[3])] ^ cast_sbox7[U_INT8_Ta(x[2])]; 154 t[1] = z[1] = x[2] ^ cast_sbox5[U_INT8_Ta(z[0])] ^ 155 cast_sbox6[U_INT8_Tc(z[0])] ^ cast_sbox7[U_INT8_Tb(z[0])] ^ 156 cast_sbox8[U_INT8_Td(z[0])] ^ cast_sbox8[U_INT8_Tc(x[2])]; 157 t[2] = z[2] = x[3] ^ cast_sbox5[U_INT8_Td(z[1])] ^ 158 cast_sbox6[U_INT8_Tc(z[1])] ^ cast_sbox7[U_INT8_Tb(z[1])] ^ 159 cast_sbox8[U_INT8_Ta(z[1])] ^ cast_sbox5[U_INT8_Tb(x[2])]; 160 t[3] = z[3] = x[1] ^ cast_sbox5[U_INT8_Tc(z[2])] ^ 161 cast_sbox6[U_INT8_Tb(z[2])] ^ cast_sbox7[U_INT8_Td(z[2])] ^ 162 cast_sbox8[U_INT8_Ta(z[2])] ^ cast_sbox6[U_INT8_Td(x[2])]; 163 break; 164 case 4: 165 t[0] = x[0] = z[2] ^ cast_sbox5[U_INT8_Tb(z[1])] ^ 166 cast_sbox6[U_INT8_Td(z[1])] ^ cast_sbox7[U_INT8_Ta(z[1])] ^ 167 cast_sbox8[U_INT8_Tc(z[1])] ^ cast_sbox7[U_INT8_Ta(z[0])]; 168 t[1] = x[1] = z[0] ^ cast_sbox5[U_INT8_Ta(x[0])] ^ 169 cast_sbox6[U_INT8_Tc(x[0])] ^ cast_sbox7[U_INT8_Tb(x[0])] ^ 170 cast_sbox8[U_INT8_Td(x[0])] ^ cast_sbox8[U_INT8_Tc(z[0])]; 171 t[2] = x[2] = z[1] ^ cast_sbox5[U_INT8_Td(x[1])] ^ 172 cast_sbox6[U_INT8_Tc(x[1])] ^ cast_sbox7[U_INT8_Tb(x[1])] ^ 173 cast_sbox8[U_INT8_Ta(x[1])] ^ cast_sbox5[U_INT8_Tb(z[0])]; 174 t[3] = x[3] = z[3] ^ cast_sbox5[U_INT8_Tc(x[2])] ^ 175 cast_sbox6[U_INT8_Tb(x[2])] ^ cast_sbox7[U_INT8_Td(x[2])] ^ 176 cast_sbox8[U_INT8_Ta(x[2])] ^ cast_sbox6[U_INT8_Td(z[0])]; 177 break; 178 } 179 switch (i & 12) { 180 case 0: 181 case 12: 182 key->xkey[i+0] = cast_sbox5[U_INT8_Ta(t[2])] ^ cast_sbox6[U_INT8_Tb(t[2])] ^ 183 cast_sbox7[U_INT8_Td(t[1])] ^ cast_sbox8[U_INT8_Tc(t[1])]; 184 key->xkey[i+1] = cast_sbox5[U_INT8_Tc(t[2])] ^ cast_sbox6[U_INT8_Td(t[2])] ^ 185 cast_sbox7[U_INT8_Tb(t[1])] ^ cast_sbox8[U_INT8_Ta(t[1])]; 186 key->xkey[i+2] = cast_sbox5[U_INT8_Ta(t[3])] ^ cast_sbox6[U_INT8_Tb(t[3])] ^ 187 cast_sbox7[U_INT8_Td(t[0])] ^ cast_sbox8[U_INT8_Tc(t[0])]; 188 key->xkey[i+3] = cast_sbox5[U_INT8_Tc(t[3])] ^ cast_sbox6[U_INT8_Td(t[3])] ^ 189 cast_sbox7[U_INT8_Tb(t[0])] ^ cast_sbox8[U_INT8_Ta(t[0])]; 190 break; 191 case 4: 192 case 8: 193 key->xkey[i+0] = cast_sbox5[U_INT8_Td(t[0])] ^ cast_sbox6[U_INT8_Tc(t[0])] ^ 194 cast_sbox7[U_INT8_Ta(t[3])] ^ cast_sbox8[U_INT8_Tb(t[3])]; 195 key->xkey[i+1] = cast_sbox5[U_INT8_Tb(t[0])] ^ cast_sbox6[U_INT8_Ta(t[0])] ^ 196 cast_sbox7[U_INT8_Tc(t[3])] ^ cast_sbox8[U_INT8_Td(t[3])]; 197 key->xkey[i+2] = cast_sbox5[U_INT8_Td(t[1])] ^ cast_sbox6[U_INT8_Tc(t[1])] ^ 198 cast_sbox7[U_INT8_Ta(t[2])] ^ cast_sbox8[U_INT8_Tb(t[2])]; 199 key->xkey[i+3] = cast_sbox5[U_INT8_Tb(t[1])] ^ cast_sbox6[U_INT8_Ta(t[1])] ^ 200 cast_sbox7[U_INT8_Tc(t[2])] ^ cast_sbox8[U_INT8_Td(t[2])]; 201 break; 202 } 203 switch (i & 12) { 204 case 0: 205 key->xkey[i+0] ^= cast_sbox5[U_INT8_Tc(z[0])]; 206 key->xkey[i+1] ^= cast_sbox6[U_INT8_Tc(z[1])]; 207 key->xkey[i+2] ^= cast_sbox7[U_INT8_Tb(z[2])]; 208 key->xkey[i+3] ^= cast_sbox8[U_INT8_Ta(z[3])]; 209 break; 210 case 4: 211 key->xkey[i+0] ^= cast_sbox5[U_INT8_Ta(x[2])]; 212 key->xkey[i+1] ^= cast_sbox6[U_INT8_Tb(x[3])]; 213 key->xkey[i+2] ^= cast_sbox7[U_INT8_Td(x[0])]; 214 key->xkey[i+3] ^= cast_sbox8[U_INT8_Td(x[1])]; 215 break; 216 case 8: 217 key->xkey[i+0] ^= cast_sbox5[U_INT8_Tb(z[2])]; 218 key->xkey[i+1] ^= cast_sbox6[U_INT8_Ta(z[3])]; 219 key->xkey[i+2] ^= cast_sbox7[U_INT8_Tc(z[0])]; 220 key->xkey[i+3] ^= cast_sbox8[U_INT8_Tc(z[1])]; 221 break; 222 case 12: 223 key->xkey[i+0] ^= cast_sbox5[U_INT8_Td(x[0])]; 224 key->xkey[i+1] ^= cast_sbox6[U_INT8_Td(x[1])]; 225 key->xkey[i+2] ^= cast_sbox7[U_INT8_Ta(x[2])]; 226 key->xkey[i+3] ^= cast_sbox8[U_INT8_Tb(x[3])]; 227 break; 228 } 229 if (i >= 16) { 230 key->xkey[i+0] &= 31; 231 key->xkey[i+1] &= 31; 232 key->xkey[i+2] &= 31; 233 key->xkey[i+3] &= 31; 234 } 235 } 236 /* Wipe clean */ 237 for (i = 0; i < 4; i++) { 238 t[i] = x[i] = z[i] = 0; 239 } 240 } 241 242 /* Made in Canada */ 243 244