| /* |
| * Copyright (C) 2017 Denys Vlasenko |
| * |
| * Licensed under GPLv2, see file LICENSE in this source tree. |
| */ |
| |
| |
| /* The part below is a section of matrixssl-3-7-2b-open/crypto/cryptolib.h |
| * Changes are flagged with //bbox |
| * TODO: |
| * Take a look at "roll %%cl" part... rotates by constant use fewer registers, |
| * and on many Intel CPUs rotates by %cl are slower: they take 2 cycles, not 1. |
| */ |
| |
| /******************************************************************************/ |
| /* 32-bit Rotates */ |
| /******************************************************************************/ |
| #if defined(_MSC_VER) |
| /******************************************************************************/ |
| |
| /* instrinsic rotate */ |
| #include <stdlib.h> |
| #pragma intrinsic(_lrotr,_lrotl) |
| #define ROR(x,n) _lrotr(x,n) |
| #define ROL(x,n) _lrotl(x,n) |
| |
| /******************************************************************************/ |
| #elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) && \ |
| !defined(INTEL_CC) && !defined(PS_NO_ASM) |
| |
| static inline unsigned ROL(unsigned word, int i) |
| { |
| asm ("roll %%cl,%0" |
| :"=r" (word) |
| :"0" (word),"c" (i)); |
| return word; |
| } |
| |
| static inline unsigned ROR(unsigned word, int i) |
| { |
| asm ("rorl %%cl,%0" |
| :"=r" (word) |
| :"0" (word),"c" (i)); |
| return word; |
| } |
| |
| /******************************************************************************/ |
| #else |
| |
| /* rotates the hard way */ |
| #define ROL(x, y) \ |
| ( (((unsigned long)(x)<<(unsigned long)((y)&31)) | \ |
| (((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)(32-((y)&31)))) & \ |
| 0xFFFFFFFFUL) |
| #define ROR(x, y) \ |
| ( ((((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)((y)&31)) | \ |
| ((unsigned long)(x)<<(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL) |
| |
| #endif /* 32-bit Rotates */ |
| /******************************************************************************/ |
| |
| #ifdef HAVE_NATIVE_INT64 |
| #ifdef _MSC_VER |
| #define CONST64(n) n ## ui64 |
| #else |
| #define CONST64(n) n ## ULL |
| #endif |
| #endif |
| |
| /******************************************************************************/ |
| /* |
| Endian helper macros |
| */ |
| #if defined (ENDIAN_NEUTRAL) |
| #define STORE32L(x, y) { \ |
| (y)[3] = (unsigned char)(((x)>>24)&255); \ |
| (y)[2] = (unsigned char)(((x)>>16)&255); \ |
| (y)[1] = (unsigned char)(((x)>>8)&255); \ |
| (y)[0] = (unsigned char)((x)&255); \ |
| } |
| |
| #define LOAD32L(x, y) { \ |
| x = ((unsigned long)((y)[3] & 255)<<24) | \ |
| ((unsigned long)((y)[2] & 255)<<16) | \ |
| ((unsigned long)((y)[1] & 255)<<8) | \ |
| ((unsigned long)((y)[0] & 255)); \ |
| } |
| |
| #define STORE64L(x, y) { \ |
| (y)[7] = (unsigned char)(((x)>>56)&255); \ |
| (y)[6] = (unsigned char)(((x)>>48)&255); \ |
| (y)[5] = (unsigned char)(((x)>>40)&255); \ |
| (y)[4] = (unsigned char)(((x)>>32)&255); \ |
| (y)[3] = (unsigned char)(((x)>>24)&255); \ |
| (y)[2] = (unsigned char)(((x)>>16)&255); \ |
| (y)[1] = (unsigned char)(((x)>>8)&255); \ |
| (y)[0] = (unsigned char)((x)&255); \ |
| } |
| |
| #define LOAD64L(x, y) { \ |
| x = (((uint64)((y)[7] & 255))<<56)|(((uint64)((y)[6] & 255))<<48)| \ |
| (((uint64)((y)[5] & 255))<<40)|(((uint64)((y)[4] & 255))<<32)| \ |
| (((uint64)((y)[3] & 255))<<24)|(((uint64)((y)[2] & 255))<<16)| \ |
| (((uint64)((y)[1] & 255))<<8)|(((uint64)((y)[0] & 255))); \ |
| } |
| |
| #define STORE32H(x, y) { \ |
| (y)[0] = (unsigned char)(((x)>>24)&255); \ |
| (y)[1] = (unsigned char)(((x)>>16)&255); \ |
| (y)[2] = (unsigned char)(((x)>>8)&255); \ |
| (y)[3] = (unsigned char)((x)&255); \ |
| } |
| |
| #define LOAD32H(x, y) { \ |
| x = ((unsigned long)((y)[0] & 255)<<24) | \ |
| ((unsigned long)((y)[1] & 255)<<16) | \ |
| ((unsigned long)((y)[2] & 255)<<8) | \ |
| ((unsigned long)((y)[3] & 255)); \ |
| } |
| |
| #define STORE64H(x, y) { \ |
| (y)[0] = (unsigned char)(((x)>>56)&255); \ |
| (y)[1] = (unsigned char)(((x)>>48)&255); \ |
| (y)[2] = (unsigned char)(((x)>>40)&255); \ |
| (y)[3] = (unsigned char)(((x)>>32)&255); \ |
| (y)[4] = (unsigned char)(((x)>>24)&255); \ |
| (y)[5] = (unsigned char)(((x)>>16)&255); \ |
| (y)[6] = (unsigned char)(((x)>>8)&255); \ |
| (y)[7] = (unsigned char)((x)&255); \ |
| } |
| |
| #define LOAD64H(x, y) { \ |
| x = (((uint64)((y)[0] & 255))<<56)|(((uint64)((y)[1] & 255))<<48) | \ |
| (((uint64)((y)[2] & 255))<<40)|(((uint64)((y)[3] & 255))<<32) | \ |
| (((uint64)((y)[4] & 255))<<24)|(((uint64)((y)[5] & 255))<<16) | \ |
| (((uint64)((y)[6] & 255))<<8)|(((uint64)((y)[7] & 255))); \ |
| } |
| |
| #endif /* ENDIAN_NEUTRAL */ |
| |
| #ifdef ENDIAN_LITTLE |
| #define STORE32H(x, y) { \ |
| (y)[0] = (unsigned char)(((x)>>24)&255); \ |
| (y)[1] = (unsigned char)(((x)>>16)&255); \ |
| (y)[2] = (unsigned char)(((x)>>8)&255); \ |
| (y)[3] = (unsigned char)((x)&255); \ |
| } |
| |
| #define LOAD32H(x, y) { \ |
| x = ((unsigned long)((y)[0] & 255)<<24) | \ |
| ((unsigned long)((y)[1] & 255)<<16) | \ |
| ((unsigned long)((y)[2] & 255)<<8) | \ |
| ((unsigned long)((y)[3] & 255)); \ |
| } |
| |
| #define STORE64H(x, y) { \ |
| (y)[0] = (unsigned char)(((x)>>56)&255); \ |
| (y)[1] = (unsigned char)(((x)>>48)&255); \ |
| (y)[2] = (unsigned char)(((x)>>40)&255); \ |
| (y)[3] = (unsigned char)(((x)>>32)&255); \ |
| (y)[4] = (unsigned char)(((x)>>24)&255); \ |
| (y)[5] = (unsigned char)(((x)>>16)&255); \ |
| (y)[6] = (unsigned char)(((x)>>8)&255); \ |
| (y)[7] = (unsigned char)((x)&255); \ |
| } |
| |
| #define LOAD64H(x, y) { \ |
| x = (((uint64)((y)[0] & 255))<<56)|(((uint64)((y)[1] & 255))<<48) | \ |
| (((uint64)((y)[2] & 255))<<40)|(((uint64)((y)[3] & 255))<<32) | \ |
| (((uint64)((y)[4] & 255))<<24)|(((uint64)((y)[5] & 255))<<16) | \ |
| (((uint64)((y)[6] & 255))<<8)|(((uint64)((y)[7] & 255))); } |
| |
| #ifdef ENDIAN_32BITWORD |
| #define STORE32L(x, y) { \ |
| unsigned long __t = (x); memcpy(y, &__t, 4); \ |
| } |
| |
| #define LOAD32L(x, y) memcpy(&(x), y, 4); |
| |
| #define STORE64L(x, y) { \ |
| (y)[7] = (unsigned char)(((x)>>56)&255); \ |
| (y)[6] = (unsigned char)(((x)>>48)&255); \ |
| (y)[5] = (unsigned char)(((x)>>40)&255); \ |
| (y)[4] = (unsigned char)(((x)>>32)&255); \ |
| (y)[3] = (unsigned char)(((x)>>24)&255); \ |
| (y)[2] = (unsigned char)(((x)>>16)&255); \ |
| (y)[1] = (unsigned char)(((x)>>8)&255); \ |
| (y)[0] = (unsigned char)((x)&255); \ |
| } |
| |
| #define LOAD64L(x, y) { \ |
| x = (((uint64)((y)[7] & 255))<<56)|(((uint64)((y)[6] & 255))<<48)| \ |
| (((uint64)((y)[5] & 255))<<40)|(((uint64)((y)[4] & 255))<<32)| \ |
| (((uint64)((y)[3] & 255))<<24)|(((uint64)((y)[2] & 255))<<16)| \ |
| (((uint64)((y)[1] & 255))<<8)|(((uint64)((y)[0] & 255))); \ |
| } |
| |
| #else /* 64-bit words then */ |
| #define STORE32L(x, y) \ |
| { unsigned long __t = (x); memcpy(y, &__t, 4); } |
| |
| #define LOAD32L(x, y) \ |
| { memcpy(&(x), y, 4); x &= 0xFFFFFFFF; } |
| |
| #define STORE64L(x, y) \ |
| { uint64 __t = (x); memcpy(y, &__t, 8); } |
| |
| #define LOAD64L(x, y) \ |
| { memcpy(&(x), y, 8); } |
| |
| #endif /* ENDIAN_64BITWORD */ |
| #endif /* ENDIAN_LITTLE */ |
| |
| #ifdef ENDIAN_BIG |
| #define STORE32L(x, y) { \ |
| (y)[3] = (unsigned char)(((x)>>24)&255); \ |
| (y)[2] = (unsigned char)(((x)>>16)&255); \ |
| (y)[1] = (unsigned char)(((x)>>8)&255); \ |
| (y)[0] = (unsigned char)((x)&255); \ |
| } |
| |
| #define LOAD32L(x, y) { \ |
| x = ((unsigned long)((y)[3] & 255)<<24) | \ |
| ((unsigned long)((y)[2] & 255)<<16) | \ |
| ((unsigned long)((y)[1] & 255)<<8) | \ |
| ((unsigned long)((y)[0] & 255)); \ |
| } |
| |
| #define STORE64L(x, y) { \ |
| (y)[7] = (unsigned char)(((x)>>56)&255); \ |
| (y)[6] = (unsigned char)(((x)>>48)&255); \ |
| (y)[5] = (unsigned char)(((x)>>40)&255); \ |
| (y)[4] = (unsigned char)(((x)>>32)&255); \ |
| (y)[3] = (unsigned char)(((x)>>24)&255); \ |
| (y)[2] = (unsigned char)(((x)>>16)&255); \ |
| (y)[1] = (unsigned char)(((x)>>8)&255); \ |
| (y)[0] = (unsigned char)((x)&255); \ |
| } |
| |
| #define LOAD64L(x, y) { \ |
| x = (((uint64)((y)[7] & 255))<<56)|(((uint64)((y)[6] & 255))<<48) | \ |
| (((uint64)((y)[5] & 255))<<40)|(((uint64)((y)[4] & 255))<<32) | \ |
| (((uint64)((y)[3] & 255))<<24)|(((uint64)((y)[2] & 255))<<16) | \ |
| (((uint64)((y)[1] & 255))<<8)|(((uint64)((y)[0] & 255))); \ |
| } |
| |
| #ifdef ENDIAN_32BITWORD |
| #define STORE32H(x, y) \ |
| { unsigned int __t = (x); memcpy(y, &__t, 4); } |
| |
| #define LOAD32H(x, y) memcpy(&(x), y, 4); |
| |
| #define STORE64H(x, y) { \ |
| (y)[0] = (unsigned char)(((x)>>56)&255); \ |
| (y)[1] = (unsigned char)(((x)>>48)&255); \ |
| (y)[2] = (unsigned char)(((x)>>40)&255); \ |
| (y)[3] = (unsigned char)(((x)>>32)&255); \ |
| (y)[4] = (unsigned char)(((x)>>24)&255); \ |
| (y)[5] = (unsigned char)(((x)>>16)&255); \ |
| (y)[6] = (unsigned char)(((x)>>8)&255); \ |
| (y)[7] = (unsigned char)((x)&255); \ |
| } |
| |
| #define LOAD64H(x, y) { \ |
| x = (((uint64)((y)[0] & 255))<<56)|(((uint64)((y)[1] & 255))<<48)| \ |
| (((uint64)((y)[2] & 255))<<40)|(((uint64)((y)[3] & 255))<<32)| \ |
| (((uint64)((y)[4] & 255))<<24)|(((uint64)((y)[5] & 255))<<16)| \ |
| (((uint64)((y)[6] & 255))<<8)| (((uint64)((y)[7] & 255))); \ |
| } |
| |
| #else /* 64-bit words then */ |
| |
| #define STORE32H(x, y) \ |
| { unsigned long __t = (x); memcpy(y, &__t, 4); } |
| |
| #define LOAD32H(x, y) \ |
| { memcpy(&(x), y, 4); x &= 0xFFFFFFFF; } |
| |
| #define STORE64H(x, y) \ |
| { uint64 __t = (x); memcpy(y, &__t, 8); } |
| |
| #define LOAD64H(x, y) \ |
| { memcpy(&(x), y, 8); } |
| |
| #endif /* ENDIAN_64BITWORD */ |
| #endif /* ENDIAN_BIG */ |
| |
| #ifdef HAVE_NATIVE_INT64 |
| #define ROL64c(x, y) \ |
| ( (((x)<<((uint64)(y)&63)) | \ |
| (((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((uint64)64-((y)&63)))) & CONST64(0xFFFFFFFFFFFFFFFF)) |
| |
| #define ROR64c(x, y) \ |
| ( ((((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((uint64)(y)&CONST64(63))) | \ |
| ((x)<<((uint64)(64-((y)&CONST64(63)))))) & CONST64(0xFFFFFFFFFFFFFFFF)) |
| #endif /* HAVE_NATIVE_INT64 */ |
| /******************************************************************************/ |
| |
| |
| |
| /* The part below is taken almost verbatim from matrixssl-3-7-2b-open/crypto/symmetric/. |
| * Changes are flagged with //bbox |
| */ |
| |
| /** |
| * @file symmetric.h |
| * @version 33ef80f (HEAD, tag: MATRIXSSL-3-7-2-OPEN, tag: MATRIXSSL-3-7-2-COMM, origin/master, origin/HEAD, master) |
| * |
| * Header for internal symmetric key cryptography support. |
| */ |
| /* |
| * Copyright (c) 2013-2015 INSIDE Secure Corporation |
| * Copyright (c) PeerSec Networks, 2002-2011 |
| * All Rights Reserved |
| * |
| * The latest version of this code is available at http://www.matrixssl.org |
| * |
| * This software is open source; you can redistribute it and/or modify |
| * it under the terms of the GNU General Public License as published by |
| * the Free Software Foundation; either version 2 of the License, or |
| * (at your option) any later version. |
| * |
| * This General Public License does NOT permit incorporating this software |
| * into proprietary programs. If you are unable to comply with the GPL, a |
| * commercial license for this software may be purchased from INSIDE at |
| * http://www.insidesecure.com/eng/Company/Locations |
| * |
| * This program is distributed in WITHOUT ANY WARRANTY; without even the |
| * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
| * See the GNU General Public License for more details. |
| * |
| * You should have received a copy of the GNU General Public License |
| * along with this program; if not, write to the Free Software |
| * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| * http://www.gnu.org/copyleft/gpl.html |
| */ |
| /******************************************************************************/ |
| |
| #ifndef _h_PS_SYMMETRIC |
| #define _h_PS_SYMMETRIC |
| |
| /******************************************************************************/ |
| #ifdef USE_AES |
| /******************************************************************************/ |
| |
| |
| #ifndef USE_AES_CBC_EXTERNAL |
| typedef struct { |
| uint32 eK[64], dK[64]; |
| int32 Nr; |
| } psAesKey_t; |
| |
| typedef struct { |
| int32 blocklen; |
| unsigned char IV[16]; |
| psAesKey_t key; |
| #if defined(USE_AES_GCM) || defined(USE_AES_CCM) |
| unsigned char EncCtr[16]; |
| unsigned char CtrBlock[16]; |
| #endif |
| #ifdef USE_AES_GCM |
| unsigned char gInit[16]; |
| uint32 TagTemp[4]; |
| unsigned char Hash_SubKey[16]; |
| uint32 ProcessedBitCount[4]; |
| uint32 InputBufferCount; |
| uint32 OutputBufferCount; |
| union |
| { |
| unsigned char Buffer[128]; |
| uint32 BufferAlignment; |
| } Input; |
| #endif /* USE_AES_GCM */ |
| #ifdef USE_AES_CCM |
| uint32_t ccmTagTemp[16 / sizeof(uint32_t)]; /* 32 */ |
| union |
| { |
| /* Used for formatting IV. */ |
| uint8_t Temporary[16]; |
| /* Used for processing Mac. */ |
| uint8_t Y0[16]; |
| } u; /* 48 */ |
| #endif /* USE_AES_CCM */ |
| } psAesCipher_t; |
| #endif /* USE_AES_CBC_EXTERNAL */ |
| |
| #endif /* USE_AES */ |
| |
| #ifdef USE_IDEA |
| #define SSL_IDEA_KEY_LEN 16 |
| #define SSL_IDEA_IV_LEN 8 |
| #define SSL_IDEA_BLOCK_LEN 8 |
| |
| typedef struct { |
| uint16 key_schedule[52]; |
| } psIdeaKey_t; |
| |
| typedef struct { |
| psIdeaKey_t key; |
| uint32 IV[2]; |
| short for_encryption; |
| short inverted; |
| } idea_CBC; |
| #endif |
| /******************************************************************************/ |
| |
| /******************************************************************************/ |
| #ifdef USE_SEED |
| /******************************************************************************/ |
| #define SSL_SEED_KEY_LEN 16 |
| #define SSL_SEED_IV_LEN 16 |
| |
| |
| typedef struct { |
| uint32 K[32], dK[32]; |
| } psSeedKey_t; |
| |
| typedef struct { |
| int32 blocklen; |
| unsigned char IV[16]; |
| psSeedKey_t key; |
| } seed_CBC; |
| |
| #endif /* USE_SEED */ |
| /******************************************************************************/ |
| |
| /******************************************************************************/ |
| #if defined(USE_3DES) || defined(USE_DES) |
| /******************************************************************************/ |
| #define DES3_KEY_LEN 24 |
| #define DES3_IV_LEN 8 |
| #define DES_KEY_LEN 8 |
| |
| typedef struct { |
| uint32 ek[3][32], dk[3][32]; |
| } psDes3Key_t; |
| |
| /* |
| A block cipher CBC structure |
| */ |
| typedef struct { |
| int32 blocklen; |
| unsigned char IV[8]; |
| psDes3Key_t key; |
| } des3_CBC; |
| |
| #endif /* USE_3DES || USE_DES */ |
| /******************************************************************************/ |
| |
| /******************************************************************************/ |
| #ifdef USE_ARC4 |
| typedef struct { |
| unsigned char state[256]; |
| uint32 byteCount; |
| unsigned char x; |
| unsigned char y; |
| } psRc4Key_t; |
| #endif /* USE_ARC4 */ |
| /******************************************************************************/ |
| #ifdef USE_RC2 |
| typedef struct { |
| unsigned xkey[64]; |
| } psRc2Key_t; |
| |
| typedef struct { |
| int32 blocklen; |
| unsigned char IV[8]; |
| psRc2Key_t key; |
| } rc2_CBC; |
| #endif /* USE_RC2 */ |
| /******************************************************************************/ |
| /* Universal types and defines */ |
| /******************************************************************************/ |
| #define MAXBLOCKSIZE 24 |
| |
| typedef union { |
| #ifdef USE_RC2 |
| rc2_CBC rc2; |
| #endif |
| #ifdef USE_ARC4 |
| psRc4Key_t arc4; |
| #endif |
| #ifdef USE_3DES |
| des3_CBC des3; |
| #endif |
| #ifdef USE_AES |
| psAesCipher_t aes; |
| #endif |
| #ifdef USE_SEED |
| seed_CBC seed; |
| #endif |
| #ifdef USE_IDEA |
| idea_CBC idea; |
| #endif |
| } psCipherContext_t; |
| |
| #define byte(x, n) (((x) >> (8 * (n))) & 255) |
| |
| #endif /* _h_PS_SYMMETRIC */ |
| /******************************************************************************/ |