blob: b6b55c78c8f6e552a5f0795e7f15efc39dd99d52 [file] [log] [blame]
Denys Vlasenkob7e9ae62017-01-18 17:20:27 +01001/*
2 * Copyright (C) 2017 Denys Vlasenko
3 *
4 * Licensed under GPLv2, see file LICENSE in this source tree.
5 */
6
7
8/* The part below is a section of matrixssl-3-7-2b-open/crypto/cryptolib.h
Denys Vlasenko6b1b0042017-01-19 15:51:00 +01009 * Changes are flagged with //bbox
Denys Vlasenkob7e9ae62017-01-18 17:20:27 +010010 * TODO:
11 * Take a look at "roll %%cl" part... rotates by constant use fewer registers,
12 * and on many Intel CPUs rotates by %cl are slower: they take 2 cycles, not 1.
13 */
14
15/******************************************************************************/
16/* 32-bit Rotates */
17/******************************************************************************/
18#if defined(_MSC_VER)
19/******************************************************************************/
20
21/* instrinsic rotate */
22#include <stdlib.h>
23#pragma intrinsic(_lrotr,_lrotl)
24#define ROR(x,n) _lrotr(x,n)
25#define ROL(x,n) _lrotl(x,n)
26
27/******************************************************************************/
28#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) && \
29 !defined(INTEL_CC) && !defined(PS_NO_ASM)
30
31static inline unsigned ROL(unsigned word, int i)
32{
33 asm ("roll %%cl,%0"
34 :"=r" (word)
35 :"0" (word),"c" (i));
36 return word;
37}
38
39static inline unsigned ROR(unsigned word, int i)
40{
41 asm ("rorl %%cl,%0"
42 :"=r" (word)
43 :"0" (word),"c" (i));
44 return word;
45}
46
47/******************************************************************************/
48#else
49
50/* rotates the hard way */
51#define ROL(x, y) \
52 ( (((unsigned long)(x)<<(unsigned long)((y)&31)) | \
53 (((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)(32-((y)&31)))) & \
54 0xFFFFFFFFUL)
55#define ROR(x, y) \
56 ( ((((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)((y)&31)) | \
57 ((unsigned long)(x)<<(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL)
58
59#endif /* 32-bit Rotates */
60/******************************************************************************/
61
62#ifdef HAVE_NATIVE_INT64
63#ifdef _MSC_VER
64 #define CONST64(n) n ## ui64
65#else
66 #define CONST64(n) n ## ULL
67#endif
68#endif
69
70/******************************************************************************/
71/*
72 Endian helper macros
73 */
74#if defined (ENDIAN_NEUTRAL)
75#define STORE32L(x, y) { \
76(y)[3] = (unsigned char)(((x)>>24)&255); \
77(y)[2] = (unsigned char)(((x)>>16)&255); \
78(y)[1] = (unsigned char)(((x)>>8)&255); \
79(y)[0] = (unsigned char)((x)&255); \
80}
81
82#define LOAD32L(x, y) { \
83x = ((unsigned long)((y)[3] & 255)<<24) | \
84((unsigned long)((y)[2] & 255)<<16) | \
85((unsigned long)((y)[1] & 255)<<8) | \
86((unsigned long)((y)[0] & 255)); \
87}
88
89#define STORE64L(x, y) { \
90(y)[7] = (unsigned char)(((x)>>56)&255); \
91(y)[6] = (unsigned char)(((x)>>48)&255); \
92(y)[5] = (unsigned char)(((x)>>40)&255); \
93(y)[4] = (unsigned char)(((x)>>32)&255); \
94(y)[3] = (unsigned char)(((x)>>24)&255); \
95(y)[2] = (unsigned char)(((x)>>16)&255); \
96(y)[1] = (unsigned char)(((x)>>8)&255); \
97(y)[0] = (unsigned char)((x)&255); \
98}
99
100#define LOAD64L(x, y) { \
101x = (((uint64)((y)[7] & 255))<<56)|(((uint64)((y)[6] & 255))<<48)| \
102(((uint64)((y)[5] & 255))<<40)|(((uint64)((y)[4] & 255))<<32)| \
103(((uint64)((y)[3] & 255))<<24)|(((uint64)((y)[2] & 255))<<16)| \
104(((uint64)((y)[1] & 255))<<8)|(((uint64)((y)[0] & 255))); \
105}
106
107#define STORE32H(x, y) { \
108(y)[0] = (unsigned char)(((x)>>24)&255); \
109(y)[1] = (unsigned char)(((x)>>16)&255); \
110(y)[2] = (unsigned char)(((x)>>8)&255); \
111(y)[3] = (unsigned char)((x)&255); \
112}
113
114#define LOAD32H(x, y) { \
115x = ((unsigned long)((y)[0] & 255)<<24) | \
116((unsigned long)((y)[1] & 255)<<16) | \
117((unsigned long)((y)[2] & 255)<<8) | \
118((unsigned long)((y)[3] & 255)); \
119}
120
121#define STORE64H(x, y) { \
122(y)[0] = (unsigned char)(((x)>>56)&255); \
123(y)[1] = (unsigned char)(((x)>>48)&255); \
124(y)[2] = (unsigned char)(((x)>>40)&255); \
125(y)[3] = (unsigned char)(((x)>>32)&255); \
126(y)[4] = (unsigned char)(((x)>>24)&255); \
127(y)[5] = (unsigned char)(((x)>>16)&255); \
128(y)[6] = (unsigned char)(((x)>>8)&255); \
129(y)[7] = (unsigned char)((x)&255); \
130}
131
132#define LOAD64H(x, y) { \
133x = (((uint64)((y)[0] & 255))<<56)|(((uint64)((y)[1] & 255))<<48) | \
134(((uint64)((y)[2] & 255))<<40)|(((uint64)((y)[3] & 255))<<32) | \
135(((uint64)((y)[4] & 255))<<24)|(((uint64)((y)[5] & 255))<<16) | \
136(((uint64)((y)[6] & 255))<<8)|(((uint64)((y)[7] & 255))); \
137}
138
139#endif /* ENDIAN_NEUTRAL */
140
141#ifdef ENDIAN_LITTLE
142#define STORE32H(x, y) { \
143(y)[0] = (unsigned char)(((x)>>24)&255); \
144(y)[1] = (unsigned char)(((x)>>16)&255); \
145(y)[2] = (unsigned char)(((x)>>8)&255); \
146(y)[3] = (unsigned char)((x)&255); \
147}
148
149#define LOAD32H(x, y) { \
150x = ((unsigned long)((y)[0] & 255)<<24) | \
151((unsigned long)((y)[1] & 255)<<16) | \
152((unsigned long)((y)[2] & 255)<<8) | \
153((unsigned long)((y)[3] & 255)); \
154}
155
156#define STORE64H(x, y) { \
157(y)[0] = (unsigned char)(((x)>>56)&255); \
158(y)[1] = (unsigned char)(((x)>>48)&255); \
159(y)[2] = (unsigned char)(((x)>>40)&255); \
160(y)[3] = (unsigned char)(((x)>>32)&255); \
161(y)[4] = (unsigned char)(((x)>>24)&255); \
162(y)[5] = (unsigned char)(((x)>>16)&255); \
163(y)[6] = (unsigned char)(((x)>>8)&255); \
164(y)[7] = (unsigned char)((x)&255); \
165}
166
167#define LOAD64H(x, y) { \
168x = (((uint64)((y)[0] & 255))<<56)|(((uint64)((y)[1] & 255))<<48) | \
169(((uint64)((y)[2] & 255))<<40)|(((uint64)((y)[3] & 255))<<32) | \
170(((uint64)((y)[4] & 255))<<24)|(((uint64)((y)[5] & 255))<<16) | \
171(((uint64)((y)[6] & 255))<<8)|(((uint64)((y)[7] & 255))); }
172
173#ifdef ENDIAN_32BITWORD
174#define STORE32L(x, y) { \
175unsigned long __t = (x); memcpy(y, &__t, 4); \
176}
177
178#define LOAD32L(x, y) memcpy(&(x), y, 4);
179
180#define STORE64L(x, y) { \
181(y)[7] = (unsigned char)(((x)>>56)&255); \
182(y)[6] = (unsigned char)(((x)>>48)&255); \
183(y)[5] = (unsigned char)(((x)>>40)&255); \
184(y)[4] = (unsigned char)(((x)>>32)&255); \
185(y)[3] = (unsigned char)(((x)>>24)&255); \
186(y)[2] = (unsigned char)(((x)>>16)&255); \
187(y)[1] = (unsigned char)(((x)>>8)&255); \
188(y)[0] = (unsigned char)((x)&255); \
189}
190
191#define LOAD64L(x, y) { \
192x = (((uint64)((y)[7] & 255))<<56)|(((uint64)((y)[6] & 255))<<48)| \
193(((uint64)((y)[5] & 255))<<40)|(((uint64)((y)[4] & 255))<<32)| \
194(((uint64)((y)[3] & 255))<<24)|(((uint64)((y)[2] & 255))<<16)| \
195(((uint64)((y)[1] & 255))<<8)|(((uint64)((y)[0] & 255))); \
196}
197
198#else /* 64-bit words then */
199#define STORE32L(x, y) \
200{ unsigned long __t = (x); memcpy(y, &__t, 4); }
201
202#define LOAD32L(x, y) \
203{ memcpy(&(x), y, 4); x &= 0xFFFFFFFF; }
204
205#define STORE64L(x, y) \
206{ uint64 __t = (x); memcpy(y, &__t, 8); }
207
208#define LOAD64L(x, y) \
209{ memcpy(&(x), y, 8); }
210
211#endif /* ENDIAN_64BITWORD */
212#endif /* ENDIAN_LITTLE */
213
214#ifdef ENDIAN_BIG
215#define STORE32L(x, y) { \
216(y)[3] = (unsigned char)(((x)>>24)&255); \
217(y)[2] = (unsigned char)(((x)>>16)&255); \
218(y)[1] = (unsigned char)(((x)>>8)&255); \
219(y)[0] = (unsigned char)((x)&255); \
220}
221
222#define LOAD32L(x, y) { \
223x = ((unsigned long)((y)[3] & 255)<<24) | \
224((unsigned long)((y)[2] & 255)<<16) | \
225((unsigned long)((y)[1] & 255)<<8) | \
226((unsigned long)((y)[0] & 255)); \
227}
228
229#define STORE64L(x, y) { \
230(y)[7] = (unsigned char)(((x)>>56)&255); \
231(y)[6] = (unsigned char)(((x)>>48)&255); \
232(y)[5] = (unsigned char)(((x)>>40)&255); \
233(y)[4] = (unsigned char)(((x)>>32)&255); \
234(y)[3] = (unsigned char)(((x)>>24)&255); \
235(y)[2] = (unsigned char)(((x)>>16)&255); \
236(y)[1] = (unsigned char)(((x)>>8)&255); \
237(y)[0] = (unsigned char)((x)&255); \
238}
239
240#define LOAD64L(x, y) { \
241x = (((uint64)((y)[7] & 255))<<56)|(((uint64)((y)[6] & 255))<<48) | \
242(((uint64)((y)[5] & 255))<<40)|(((uint64)((y)[4] & 255))<<32) | \
243(((uint64)((y)[3] & 255))<<24)|(((uint64)((y)[2] & 255))<<16) | \
244(((uint64)((y)[1] & 255))<<8)|(((uint64)((y)[0] & 255))); \
245}
246
247#ifdef ENDIAN_32BITWORD
248#define STORE32H(x, y) \
249{ unsigned int __t = (x); memcpy(y, &__t, 4); }
250
251#define LOAD32H(x, y) memcpy(&(x), y, 4);
252
253#define STORE64H(x, y) { \
254(y)[0] = (unsigned char)(((x)>>56)&255); \
255(y)[1] = (unsigned char)(((x)>>48)&255); \
256(y)[2] = (unsigned char)(((x)>>40)&255); \
257(y)[3] = (unsigned char)(((x)>>32)&255); \
258(y)[4] = (unsigned char)(((x)>>24)&255); \
259(y)[5] = (unsigned char)(((x)>>16)&255); \
260(y)[6] = (unsigned char)(((x)>>8)&255); \
261(y)[7] = (unsigned char)((x)&255); \
262}
263
264#define LOAD64H(x, y) { \
265x = (((uint64)((y)[0] & 255))<<56)|(((uint64)((y)[1] & 255))<<48)| \
266(((uint64)((y)[2] & 255))<<40)|(((uint64)((y)[3] & 255))<<32)| \
267(((uint64)((y)[4] & 255))<<24)|(((uint64)((y)[5] & 255))<<16)| \
268(((uint64)((y)[6] & 255))<<8)| (((uint64)((y)[7] & 255))); \
269}
270
271#else /* 64-bit words then */
272
273#define STORE32H(x, y) \
274{ unsigned long __t = (x); memcpy(y, &__t, 4); }
275
276#define LOAD32H(x, y) \
277{ memcpy(&(x), y, 4); x &= 0xFFFFFFFF; }
278
279#define STORE64H(x, y) \
280{ uint64 __t = (x); memcpy(y, &__t, 8); }
281
282#define LOAD64H(x, y) \
283{ memcpy(&(x), y, 8); }
284
285#endif /* ENDIAN_64BITWORD */
286#endif /* ENDIAN_BIG */
287
288#ifdef HAVE_NATIVE_INT64
289#define ROL64c(x, y) \
290( (((x)<<((uint64)(y)&63)) | \
291(((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((uint64)64-((y)&63)))) & CONST64(0xFFFFFFFFFFFFFFFF))
292
293#define ROR64c(x, y) \
294( ((((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((uint64)(y)&CONST64(63))) | \
295((x)<<((uint64)(64-((y)&CONST64(63)))))) & CONST64(0xFFFFFFFFFFFFFFFF))
296#endif /* HAVE_NATIVE_INT64 */
297/******************************************************************************/
298
299
300
301/* The part below is taken almost verbatim from matrixssl-3-7-2b-open/crypto/symmetric/.
Denys Vlasenko6b1b0042017-01-19 15:51:00 +0100302 * Changes are flagged with //bbox
Denys Vlasenkob7e9ae62017-01-18 17:20:27 +0100303 */
304
305/**
306 * @file symmetric.h
307 * @version 33ef80f (HEAD, tag: MATRIXSSL-3-7-2-OPEN, tag: MATRIXSSL-3-7-2-COMM, origin/master, origin/HEAD, master)
308 *
309 * Header for internal symmetric key cryptography support.
310 */
311/*
312 * Copyright (c) 2013-2015 INSIDE Secure Corporation
313 * Copyright (c) PeerSec Networks, 2002-2011
314 * All Rights Reserved
315 *
316 * The latest version of this code is available at http://www.matrixssl.org
317 *
318 * This software is open source; you can redistribute it and/or modify
319 * it under the terms of the GNU General Public License as published by
320 * the Free Software Foundation; either version 2 of the License, or
321 * (at your option) any later version.
322 *
323 * This General Public License does NOT permit incorporating this software
324 * into proprietary programs. If you are unable to comply with the GPL, a
325 * commercial license for this software may be purchased from INSIDE at
326 * http://www.insidesecure.com/eng/Company/Locations
327 *
328 * This program is distributed in WITHOUT ANY WARRANTY; without even the
329 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
330 * See the GNU General Public License for more details.
331 *
332 * You should have received a copy of the GNU General Public License
333 * along with this program; if not, write to the Free Software
334 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
335 * http://www.gnu.org/copyleft/gpl.html
336 */
337/******************************************************************************/
338
339#ifndef _h_PS_SYMMETRIC
340#define _h_PS_SYMMETRIC
341
342/******************************************************************************/
343#ifdef USE_AES
344/******************************************************************************/
345
346
347#ifndef USE_AES_CBC_EXTERNAL
348typedef struct {
349 uint32 eK[64], dK[64];
350 int32 Nr;
351} psAesKey_t;
352
353typedef struct {
354 int32 blocklen;
355 unsigned char IV[16];
356 psAesKey_t key;
357#if defined(USE_AES_GCM) || defined(USE_AES_CCM)
358 unsigned char EncCtr[16];
359 unsigned char CtrBlock[16];
360#endif
361#ifdef USE_AES_GCM
362 unsigned char gInit[16];
363 uint32 TagTemp[4];
364 unsigned char Hash_SubKey[16];
365 uint32 ProcessedBitCount[4];
366 uint32 InputBufferCount;
367 uint32 OutputBufferCount;
368 union
369 {
370 unsigned char Buffer[128];
371 uint32 BufferAlignment;
372 } Input;
373#endif /* USE_AES_GCM */
374#ifdef USE_AES_CCM
375 uint32_t ccmTagTemp[16 / sizeof(uint32_t)]; /* 32 */
376 union
377 {
378 /* Used for formatting IV. */
379 uint8_t Temporary[16];
380 /* Used for processing Mac. */
381 uint8_t Y0[16];
382 } u; /* 48 */
383#endif /* USE_AES_CCM */
384} psAesCipher_t;
385#endif /* USE_AES_CBC_EXTERNAL */
386
387#endif /* USE_AES */
388
389#ifdef USE_IDEA
390#define SSL_IDEA_KEY_LEN 16
391#define SSL_IDEA_IV_LEN 8
392#define SSL_IDEA_BLOCK_LEN 8
393
394typedef struct {
395 uint16 key_schedule[52];
396} psIdeaKey_t;
397
398typedef struct {
399 psIdeaKey_t key;
400 uint32 IV[2];
401 short for_encryption;
402 short inverted;
403} idea_CBC;
404#endif
405/******************************************************************************/
406
407/******************************************************************************/
408#ifdef USE_SEED
409/******************************************************************************/
410#define SSL_SEED_KEY_LEN 16
411#define SSL_SEED_IV_LEN 16
412
413
414typedef struct {
415 uint32 K[32], dK[32];
416} psSeedKey_t;
417
418typedef struct {
419 int32 blocklen;
420 unsigned char IV[16];
421 psSeedKey_t key;
422} seed_CBC;
423
424#endif /* USE_SEED */
425/******************************************************************************/
426
427/******************************************************************************/
428#if defined(USE_3DES) || defined(USE_DES)
429/******************************************************************************/
430#define DES3_KEY_LEN 24
431#define DES3_IV_LEN 8
432#define DES_KEY_LEN 8
433
434typedef struct {
435 uint32 ek[3][32], dk[3][32];
436} psDes3Key_t;
437
438/*
439 A block cipher CBC structure
440 */
441typedef struct {
442 int32 blocklen;
443 unsigned char IV[8];
444 psDes3Key_t key;
445} des3_CBC;
446
447#endif /* USE_3DES || USE_DES */
448/******************************************************************************/
449
450/******************************************************************************/
451#ifdef USE_ARC4
452typedef struct {
453 unsigned char state[256];
454 uint32 byteCount;
455 unsigned char x;
456 unsigned char y;
457} psRc4Key_t;
458#endif /* USE_ARC4 */
459/******************************************************************************/
460#ifdef USE_RC2
461typedef struct {
462 unsigned xkey[64];
463} psRc2Key_t;
464
465typedef struct {
466 int32 blocklen;
467 unsigned char IV[8];
468 psRc2Key_t key;
469} rc2_CBC;
470#endif /* USE_RC2 */
471/******************************************************************************/
472/* Universal types and defines */
473/******************************************************************************/
474#define MAXBLOCKSIZE 24
475
476typedef union {
477#ifdef USE_RC2
478 rc2_CBC rc2;
479#endif
480#ifdef USE_ARC4
481 psRc4Key_t arc4;
482#endif
483#ifdef USE_3DES
484 des3_CBC des3;
485#endif
486#ifdef USE_AES
487 psAesCipher_t aes;
488#endif
489#ifdef USE_SEED
490 seed_CBC seed;
491#endif
492#ifdef USE_IDEA
493 idea_CBC idea;
494#endif
495} psCipherContext_t;
496
497#define byte(x, n) (((x) >> (8 * (n))) & 255)
498
499#endif /* _h_PS_SYMMETRIC */
500/******************************************************************************/