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