comparison libtomcrypt/src/ciphers/multi2.c @ 1471:6dba84798cd5

Update to libtomcrypt 1.18.1, merged with Dropbear changes
author Matt Johnston <matt@ucc.asn.au>
date Fri, 09 Feb 2018 21:44:05 +0800
parents f849a5ca2efc
children
comparison
equal deleted inserted replaced
1470:8bba51a55704 1471:6dba84798cd5
3 * LibTomCrypt is a library that provides various cryptographic 3 * LibTomCrypt is a library that provides various cryptographic
4 * algorithms in a highly modular and flexible manner. 4 * algorithms in a highly modular and flexible manner.
5 * 5 *
6 * The library is free for all purposes without any express 6 * The library is free for all purposes without any express
7 * guarantee it works. 7 * guarantee it works.
8 *
9 * Tom St Denis, [email protected], http://libtom.org
10 */ 8 */
11 9
12 /** 10 /**
13 @file multi2.c 11 @file multi2.c
14 Multi-2 implementation (not public domain, hence the default disable) 12 Multi-2 implementation (not public domain, hence the default disable)
56 int n, t; 54 int n, t;
57 ulong32 p[2]; 55 ulong32 p[2];
58 56
59 p[0] = dk[0]; p[1] = dk[1]; 57 p[0] = dk[0]; p[1] = dk[1];
60 58
61 t = 4; 59 t = 4;
62 n = 0; 60 n = 0;
63 pi1(p); 61 pi1(p);
64 pi2(p, k); 62 pi2(p, k);
65 uk[n++] = p[0]; 63 uk[n++] = p[0];
66 pi3(p, k); 64 pi3(p, k);
81 79
82 static void encrypt(ulong32 *p, int N, ulong32 *uk) 80 static void encrypt(ulong32 *p, int N, ulong32 *uk)
83 { 81 {
84 int n, t; 82 int n, t;
85 for (t = n = 0; ; ) { 83 for (t = n = 0; ; ) {
86 pi1(p); if (++n == N) break; 84 pi1(p); if (++n == N) break;
87 pi2(p, uk+t); if (++n == N) break; 85 pi2(p, uk+t); if (++n == N) break;
88 pi3(p, uk+t); if (++n == N) break; 86 pi3(p, uk+t); if (++n == N) break;
89 pi4(p, uk+t); if (++n == N) break; 87 pi4(p, uk+t); if (++n == N) break;
90 t ^= 4; 88 t ^= 4;
91 } 89 }
92 } 90 }
93 91
94 static void decrypt(ulong32 *p, int N, ulong32 *uk) 92 static void decrypt(ulong32 *p, int N, ulong32 *uk)
95 { 93 {
96 int n, t; 94 int n, t;
97 for (t = 4*((N&1)^1), n = N; ; ) { 95 for (t = 4*(((N-1)>>2)&1), n = N; ; ) {
98 switch (n >= 4 ? 4 : 0) { 96 switch (n<=4 ? n : ((n-1)%4)+1) {
99 case 4: pi4(p, uk+t); --n; 97 case 4: pi4(p, uk+t); --n; /* FALLTHROUGH */
100 case 3: pi3(p, uk+t); --n; 98 case 3: pi3(p, uk+t); --n; /* FALLTHROUGH */
101 case 2: pi2(p, uk+t); --n; 99 case 2: pi2(p, uk+t); --n; /* FALLTHROUGH */
102 case 1: pi1(p); --n; break; 100 case 1: pi1(p); --n; break;
103 case 0: return; 101 case 0: return;
104 } 102 }
105 t ^= 4; 103 t ^= 4;
106 } 104 }
107 } 105 }
108 106
109 const struct ltc_cipher_descriptor multi2_desc = { 107 const struct ltc_cipher_descriptor multi2_desc = {
110 "multi2", 108 "multi2",
111 22, 109 22,
112 40, 40, 8, 128, 110 40, 40, 8, 128,
114 &multi2_ecb_encrypt, 112 &multi2_ecb_encrypt,
115 &multi2_ecb_decrypt, 113 &multi2_ecb_decrypt,
116 &multi2_test, 114 &multi2_test,
117 &multi2_done, 115 &multi2_done,
118 &multi2_keysize, 116 &multi2_keysize,
119 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL 117 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
120 }; 118 };
121 119
122 int multi2_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) 120 int multi2_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
123 { 121 {
124 ulong32 sk[8], dk[2]; 122 ulong32 sk[8], dk[2];
127 LTC_ARGCHK(key != NULL); 125 LTC_ARGCHK(key != NULL);
128 LTC_ARGCHK(skey != NULL); 126 LTC_ARGCHK(skey != NULL);
129 127
130 if (keylen != 40) return CRYPT_INVALID_KEYSIZE; 128 if (keylen != 40) return CRYPT_INVALID_KEYSIZE;
131 if (num_rounds == 0) num_rounds = 128; 129 if (num_rounds == 0) num_rounds = 128;
132 130
133 skey->multi2.N = num_rounds; 131 skey->multi2.N = num_rounds;
134 for (x = 0; x < 8; x++) { 132 for (x = 0; x < 8; x++) {
135 LOAD32H(sk[x], key + x*4); 133 LOAD32H(sk[x], key + x*4);
136 } 134 }
137 LOAD32H(dk[0], key + 32); 135 LOAD32H(dk[0], key + 32);
157 LTC_ARGCHK(ct != NULL); 155 LTC_ARGCHK(ct != NULL);
158 LTC_ARGCHK(skey != NULL); 156 LTC_ARGCHK(skey != NULL);
159 LOAD32H(p[0], pt); 157 LOAD32H(p[0], pt);
160 LOAD32H(p[1], pt+4); 158 LOAD32H(p[1], pt+4);
161 encrypt(p, skey->multi2.N, skey->multi2.uk); 159 encrypt(p, skey->multi2.N, skey->multi2.uk);
162 STORE32H(p[0], ct); 160 STORE32H(p[0], ct);
163 STORE32H(p[1], ct+4); 161 STORE32H(p[1], ct+4);
164 return CRYPT_OK; 162 return CRYPT_OK;
165 } 163 }
166 164
167 /** 165 /**
178 LTC_ARGCHK(ct != NULL); 176 LTC_ARGCHK(ct != NULL);
179 LTC_ARGCHK(skey != NULL); 177 LTC_ARGCHK(skey != NULL);
180 LOAD32H(p[0], ct); 178 LOAD32H(p[0], ct);
181 LOAD32H(p[1], ct+4); 179 LOAD32H(p[1], ct+4);
182 decrypt(p, skey->multi2.N, skey->multi2.uk); 180 decrypt(p, skey->multi2.N, skey->multi2.uk);
183 STORE32H(p[0], pt); 181 STORE32H(p[0], pt);
184 STORE32H(p[1], pt+4); 182 STORE32H(p[1], pt+4);
185 return CRYPT_OK; 183 return CRYPT_OK;
186 } 184 }
187 185
188 /** 186 /**
205 203
206 0x00, 0x00, 0x00, 0x00, 204 0x00, 0x00, 0x00, 0x00,
207 0x00, 0x00, 0x00, 0x00, 205 0x00, 0x00, 0x00, 0x00,
208 0x00, 0x00, 0x00, 0x00, 206 0x00, 0x00, 0x00, 0x00,
209 0x00, 0x00, 0x00, 0x00, 207 0x00, 0x00, 0x00, 0x00,
210 208
211 0x01, 0x23, 0x45, 0x67, 209 0x01, 0x23, 0x45, 0x67,
212 0x89, 0xAB, 0xCD, 0xEF 210 0x89, 0xAB, 0xCD, 0xEF
213 }, 211 },
214 { 212 {
215 0x00, 0x00, 0x00, 0x00, 213 0x00, 0x00, 0x00, 0x00,
233 0x36, 0x35, 0xd0, 0x67, 231 0x36, 0x35, 0xd0, 0x67,
234 232
235 0xb1, 0x27, 0xb9, 0x06, 233 0xb1, 0x27, 0xb9, 0x06,
236 0xe7, 0x56, 0x22, 0x38, 234 0xe7, 0x56, 0x22, 0x38,
237 }, 235 },
238 { 236 {
239 0x1f, 0xb4, 0x60, 0x60, 237 0x1f, 0xb4, 0x60, 0x60,
240 0xd0, 0xb3, 0x4f, 0xa5 238 0xd0, 0xb3, 0x4f, 0xa5
241 }, 239 },
242 { 240 {
243 0xca, 0x84, 0xa9, 0x34, 241 0xca, 0x84, 0xa9, 0x34,
256 } 254 }
257 if ((err = multi2_ecb_encrypt(tests[x].pt, buf, &skey)) != CRYPT_OK) { 255 if ((err = multi2_ecb_encrypt(tests[x].pt, buf, &skey)) != CRYPT_OK) {
258 return err; 256 return err;
259 } 257 }
260 258
261 if (XMEMCMP(buf, tests[x].ct, 8)) { 259 if (compare_testvector(buf, 8, tests[x].ct, 8, "Multi2 Encrypt", x)) {
262 return CRYPT_FAIL_TESTVECTOR; 260 return CRYPT_FAIL_TESTVECTOR;
263 } 261 }
264 262
265 if ((err = multi2_ecb_decrypt(buf, buf, &skey)) != CRYPT_OK) { 263 if ((err = multi2_ecb_decrypt(buf, buf, &skey)) != CRYPT_OK) {
266 return err; 264 return err;
267 } 265 }
268 if (XMEMCMP(buf, tests[x].pt, 8)) { 266 if (compare_testvector(buf, 8, tests[x].pt, 8, "Multi2 Decrypt", x)) {
269 return CRYPT_FAIL_TESTVECTOR; 267 return CRYPT_FAIL_TESTVECTOR;
270 } 268 }
271 } 269 }
272 270
273 return CRYPT_OK; 271 for (x = 128; x < 256; ++x) {
274 } 272 unsigned char ct[8];
275 273
276 /** Terminate the context 274 if ((err = multi2_setup(tests[0].key, 40, x, &skey)) != CRYPT_OK) {
275 return err;
276 }
277 if ((err = multi2_ecb_encrypt(tests[0].pt, ct, &skey)) != CRYPT_OK) {
278 return err;
279 }
280 if ((err = multi2_ecb_decrypt(ct, buf, &skey)) != CRYPT_OK) {
281 return err;
282 }
283 if (compare_testvector(buf, 8, tests[0].pt, 8, "Multi2 Rounds", x)) {
284 return CRYPT_FAIL_TESTVECTOR;
285 }
286 }
287
288 return CRYPT_OK;
289 }
290
291 /** Terminate the context
277 @param skey The scheduled key 292 @param skey The scheduled key
278 */ 293 */
279 void multi2_done(symmetric_key *skey) 294 void multi2_done(symmetric_key *skey)
280 { 295 {
296 LTC_UNUSED_PARAM(skey);
281 } 297 }
282 298
283 /** 299 /**
284 Gets suitable key size 300 Gets suitable key size
285 @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable. 301 @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable.
296 return CRYPT_OK; 312 return CRYPT_OK;
297 } 313 }
298 314
299 #endif 315 #endif
300 316
301 /* $Source$ */ 317 /* ref: $Format:%D$ */
302 /* $Revision$ */ 318 /* git commit: $Format:%H$ */
303 /* $Date$ */ 319 /* commit time: $Format:%ai$ */