00001 #ifndef ICE_KEY_IMPLEMENTATION_FILE
00002 #define ICE_KEY_IMPLEMENTATION_FILE
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "ice_key.h"
00020
00021 #include <basis/byte_array.h>
00022 #include <basis/chaos.h>
00023 #include <basis/function.h>
00024 #include <basis/log_base.h>
00025 #include <basis/mutex.h>
00026 #include <data_struct/static_memory_gremlin.h>
00027
00028 #include <string.h>
00029
00030 #undef LOG
00031 #define LOG(s) CLASS_EMERGENCY_LOG(program_wide_logger(), s)
00032
00033 SAFE_STATIC(mutex, __ice_box_init_lock, )
00034
00035
00036 class ice_subkey
00037 {
00038 public:
00039 unsigned int val[3];
00040 };
00041
00042
00043 static unsigned int ice_sbox[4][1024];
00044
00045
00046 static const int ice_smod[4][4] =
00047 {
00048 {333, 313, 505, 369},
00049 {379, 375, 319, 391},
00050 {361, 445, 451, 397},
00051 {397, 425, 395, 505}
00052 };
00053
00054
00055 static const int ice_sxor[4][4] =
00056 {
00057 {0x83, 0x85, 0x9b, 0xcd},
00058 {0xcc, 0xa7, 0xad, 0x41},
00059 {0x4b, 0x2e, 0xd4, 0x33},
00060 {0xea, 0xcb, 0x2e, 0x04}
00061 };
00062
00063
00064 static const unsigned int ice_pbox[32] = {
00065 0x00000001, 0x00000080, 0x00000400, 0x00002000,
00066 0x00080000, 0x00200000, 0x01000000, 0x40000000,
00067 0x00000008, 0x00000020, 0x00000100, 0x00004000,
00068 0x00010000, 0x00800000, 0x04000000, 0x20000000,
00069 0x00000004, 0x00000010, 0x00000200, 0x00008000,
00070 0x00020000, 0x00400000, 0x08000000, 0x10000000,
00071 0x00000002, 0x00000040, 0x00000800, 0x00001000,
00072 0x00040000, 0x00100000, 0x02000000, 0x80000000};
00073
00074
00075 static const int ice_keyrot[16] =
00076 {
00077 0, 1, 2, 3, 2, 1, 3, 0,
00078 1, 3, 2, 0, 3, 1, 0, 2
00079 };
00080
00081 ice_key::ice_key(int n, bool randomize)
00082 : _key_set(false),
00083 _randomizer(new chaos),
00084 _randomize(randomize)
00085 {
00086 initialize_ice_sboxes();
00087 if (n < 1) n = 1;
00088 _size = n;
00089 _rounds = n * 16;
00090 _keysched = new ice_subkey[_rounds];
00091 }
00092
00093 ice_key::~ice_key()
00094 {
00095 int i, j;
00096
00097 for (i = 0; i < _rounds; i++)
00098 for (j = 0; j < 3; j++)
00099 _keysched[i].val[j] = 0;
00100
00101 _rounds = _size = 0;
00102
00103 delete [] _keysched;
00104
00105 WHACK(_randomizer);
00106 }
00107
00108
00109
00110 static int gf_mult(register int a, register int b, register int m)
00111 {
00112 register int res = 0;
00113
00114 while (b) {
00115 if (b & 1) res ^= a;
00116
00117 a <<= 1;
00118 b >>= 1;
00119
00120 if (a >= 256) a ^= m;
00121 }
00122
00123 return res;
00124 }
00125
00126
00127 static int gf_exp7(register int b, int m)
00128 {
00129 register int x;
00130
00131 if (b == 0) return 0;
00132
00133 x = gf_mult(b, b, m);
00134 x = gf_mult(b, x, m);
00135 x = gf_mult(x, x, m);
00136 return gf_mult(b, x, m);
00137 }
00138
00139
00140 static unsigned int ice_perm32(register unsigned int x)
00141 {
00142 register unsigned int res = 0;
00143 register const unsigned int *pbox = ice_pbox;
00144
00145 while (x) {
00146 if (x & 1) res |= *pbox;
00147 pbox++;
00148 x >>= 1;
00149 }
00150
00151 return res;
00152 }
00153
00154 void ice_key::initialize_ice_sboxes()
00155 {
00156 auto_synchronizer l(__ice_box_init_lock());
00157
00158
00159 static bool ice_sboxes_initialized = false;
00160
00161
00162 if (ice_sboxes_initialized) return;
00163
00164 register int i;
00165 for (i = 0; i < 1024; i++) {
00166 int col = (i >> 1) & 0xff;
00167 int row = (i & 0x1) | ((i & 0x200) >> 8);
00168 unsigned int x;
00169
00170 x = gf_exp7(col ^ ice_sxor[0][row], ice_smod[0][row]) << 24;
00171 ice_sbox[0][i] = ice_perm32(x);
00172
00173 x = gf_exp7(col ^ ice_sxor[1][row], ice_smod[1][row]) << 16;
00174 ice_sbox[1][i] = ice_perm32(x);
00175
00176 x = gf_exp7(col ^ ice_sxor[2][row], ice_smod[2][row]) << 8;
00177 ice_sbox[2][i] = ice_perm32(x);
00178
00179 x = gf_exp7(col ^ ice_sxor[3][row], ice_smod[3][row]);
00180 ice_sbox[3][i] = ice_perm32(x);
00181 }
00182
00183 ice_sboxes_initialized = true;
00184 }
00185
00186
00187 static unsigned int ice_f(register unsigned int p, const ice_subkey *sk)
00188 {
00189 unsigned int tl, tr;
00190 unsigned int al, ar;
00191
00192
00193 tl = ((p >> 16) & 0x3ff) | (((p >> 14) | (p << 18)) & 0xffc00);
00194
00195
00196 tr = (p & 0x3ff) | ((p << 2) & 0xffc00);
00197
00198
00199
00200
00201 al = sk->val[2] & (tl ^ tr);
00202 ar = al ^ tr;
00203 al ^= tl;
00204
00205 al ^= sk->val[0];
00206 ar ^= sk->val[1];
00207
00208
00209 return ice_sbox[0][al >> 10] | ice_sbox[1][al & 0x3ff]
00210 | ice_sbox[2][ar >> 10] | ice_sbox[3][ar & 0x3ff];
00211 }
00212
00213 byte_array ice_key::int_to_bytes(u_int to_encode) const
00214 {
00215 byte_array to_return;
00216 for (int i = 0; i < 4; i++) {
00217 to_return += to_encode % 0x100;
00218 to_encode = to_encode >> 8;
00219 }
00220 return to_return;
00221 }
00222
00223 u_int ice_key::bytes_to_int(const byte_array &to_decode) const
00224 {
00225 u_int to_return = 0;
00226 for (int i = 3; i >= 0; i--) {
00227 to_return = to_return << 8;
00228 to_return += to_decode[i];
00229 }
00230 return to_return;
00231 }
00232
00233 bool ice_key::encrypt(const byte_array &ptext, byte_array &ctext) const
00234 {
00235 ctext.reset();
00236 if (!_key_set) return false;
00237 if (!ptext.length()) return false;
00238 byte_array to_encode(int_to_bytes(u_int(ptext.length())));
00239 to_encode += ptext;
00240
00241 int leftover = to_encode.length() % 8;
00242 if (leftover) {
00243 for (int i = 0; i < 8 - leftover; i++) {
00244 if (_randomize)
00245 to_encode += byte(_randomizer->inclusive(0, 255));
00246 else
00247 to_encode += 0;
00248 }
00249 }
00250 ctext.reset(to_encode.length());
00251 for (int i = 0; i < to_encode.length(); i += 8) {
00252 code_granule eight_in;
00253 code_granule eight_out;
00254 memory_assign(eight_in, &to_encode[i], 8);
00255 encrypt_eight(eight_in, eight_out);
00256 ctext.overwrite(i, byte_array(8, eight_out), 8);
00257 }
00258 return true;
00259 }
00260
00261 bool ice_key::decrypt(const byte_array &ctext, byte_array &ptext) const
00262 {
00263 ptext.reset();
00264 if (!_key_set) return false;
00265 if (!ctext.length()) return false;
00266 byte_array decoded(ctext.length());
00267 for (int i = 0; i < ctext.length(); i += 8) {
00268 code_granule eight_in;
00269 code_granule eight_out;
00270 int j;
00271 for (j = 0; j < 8; j++) {
00272 eight_in[j] = (i + j < ctext.length())? ctext[i + j] : 0;
00273 }
00274
00275 decrypt_eight(eight_in, eight_out);
00276 decoded.overwrite(i, byte_array(8, eight_out), 8);
00277 }
00278
00279
00280 byte_array length_bytes = decoded.subarray(0, 3);
00281 decoded.zap(0, 3);
00282 int original_length = int(bytes_to_int(length_bytes));
00283 if (original_length != decoded.length())
00284 decoded.zap(original_length, decoded.length() - 1);
00285 ptext = decoded;
00286 return true;
00287 }
00288
00289 void ice_key::encrypt_eight(const code_granule &ptext,
00290 code_granule &ctext) const
00291 {
00292 register int i;
00293 register unsigned int l, r;
00294
00295 l = (ptext[0] << 24) | (ptext[1] << 16) | (ptext[2] << 8) | ptext[3];
00296 r = (ptext[4] << 24) | (ptext[5] << 16) | (ptext[6] << 8) | ptext[7];
00297
00298 for (i = 0; i < _rounds; i += 2) {
00299 l ^= ice_f(r, &_keysched[i]);
00300 r ^= ice_f(l, &_keysched[i + 1]);
00301 }
00302
00303 for (i = 0; i < 4; i++) {
00304 ctext[3 - i] = byte(r & 0xff);
00305 ctext[7 - i] = byte(l & 0xff);
00306
00307 r >>= 8;
00308 l >>= 8;
00309 }
00310 }
00311
00312 void ice_key::decrypt_eight(const code_granule &ctext,
00313 code_granule &ptext) const
00314 {
00315 register int i;
00316 register unsigned int l, r;
00317
00318 l = (ctext[0] << 24) | (ctext[1] << 16) | (ctext[2] << 8) | ctext[3];
00319 r = (ctext[4] << 24) | (ctext[5] << 16) | (ctext[6] << 8) | ctext[7];
00320
00321 for (i = _rounds - 1; i > 0; i -= 2) {
00322 l ^= ice_f(r, &_keysched[i]);
00323 r ^= ice_f(l, &_keysched[i - 1]);
00324 }
00325
00326 for (i = 0; i < 4; i++) {
00327 ptext[3 - i] = byte(r & 0xff);
00328 ptext[7 - i] = byte(l & 0xff);
00329
00330 r >>= 8;
00331 l >>= 8;
00332 }
00333 }
00334
00335 void ice_key::schedule_build(u_short *kb, int n, const int *keyrot)
00336 {
00337 int i;
00338
00339 for (i = 0; i < 8; i++) {
00340 register int j;
00341 register int kr = keyrot[i];
00342 ice_subkey *isk = &_keysched[n + i];
00343
00344 for (j = 0; j < 3; j++) isk->val[j] = 0;
00345
00346 for (j = 0; j < 15; j++) {
00347 register int k;
00348 unsigned int *curr_sk = &isk->val[j % 3];
00349
00350 for (k = 0; k < 4; k++) {
00351 unsigned short *curr_kb = &kb[(kr + k) & 3];
00352 register int bit = *curr_kb & 1;
00353
00354 *curr_sk = (*curr_sk << 1) | bit;
00355 *curr_kb = (*curr_kb >> 1) | ((bit ^ 1) << 15);
00356 }
00357 }
00358 }
00359 }
00360
00361 bool ice_key::set(const byte_array &key)
00362 {
00363 FUNCDEF("set");
00364 int i;
00365 if (key.length() != _size * 8) {
00366 LOG("failure in key size; it is not the block size times 8.");
00367 return false;
00368 }
00369
00370 _key_set = true;
00371
00372 if (_rounds == 8) {
00373 unsigned short kb[4];
00374
00375 for (i = 0; i < 4; i++)
00376 kb[3 - i] = (key[i*2] << 8) | key[i*2 + 1];
00377
00378 schedule_build(kb, 0, ice_keyrot);
00379 return true;
00380 }
00381
00382 for (i = 0; i < _size; i++) {
00383 int j;
00384 unsigned short kb[4];
00385
00386 for (j = 0; j < 4; j++)
00387 kb[3 - j] = (key[i*8 + j*2] << 8) | key[i*8 + j*2 + 1];
00388
00389 schedule_build(kb, i*8, ice_keyrot);
00390 schedule_build(kb, _rounds - 8 - i*8, &ice_keyrot[8]);
00391 }
00392 return true;
00393 }
00394
00395
00396 #endif //ICE_KEY_IMPLEMENTATION_FILE
00397