1238384Sjkim/* ==================================================================== 2238384Sjkim * Copyright (c) 2010 The OpenSSL Project. All rights reserved. 3238384Sjkim * 4238384Sjkim * Redistribution and use is governed by OpenSSL license. 5238384Sjkim * ==================================================================== 6238384Sjkim */ 7238384Sjkim 8238384Sjkim#include <openssl/modes.h> 9238384Sjkim 10238384Sjkim#if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__) 11238384Sjkimtypedef __int64 i64; 12238384Sjkimtypedef unsigned __int64 u64; 13280304Sjkim# define U64(C) C##UI64 14238384Sjkim#elif defined(__arch64__) 15238384Sjkimtypedef long i64; 16238384Sjkimtypedef unsigned long u64; 17280304Sjkim# define U64(C) C##UL 18238384Sjkim#else 19238384Sjkimtypedef long long i64; 20238384Sjkimtypedef unsigned long long u64; 21280304Sjkim# define U64(C) C##ULL 22238384Sjkim#endif 23238384Sjkim 24238384Sjkimtypedef unsigned int u32; 25238384Sjkimtypedef unsigned char u8; 26238384Sjkim 27238384Sjkim#define STRICT_ALIGNMENT 1 28280304Sjkim#if defined(__i386) || defined(__i386__) || \ 29280304Sjkim defined(__x86_64) || defined(__x86_64__) || \ 30280304Sjkim defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64) || \ 31280304Sjkim defined(__s390__) || defined(__s390x__) 32238384Sjkim# undef STRICT_ALIGNMENT 33238384Sjkim#endif 34238384Sjkim 35238384Sjkim#if !defined(PEDANTIC) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) 36280304Sjkim# if defined(__GNUC__) && __GNUC__>=2 37280304Sjkim# if defined(__x86_64) || defined(__x86_64__) 38280304Sjkim# define BSWAP8(x) ({ u64 ret=(x); \ 39280304Sjkim asm ("bswapq %0" \ 40280304Sjkim : "+r"(ret)); ret; }) 41280304Sjkim# define BSWAP4(x) ({ u32 ret=(x); \ 42280304Sjkim asm ("bswapl %0" \ 43280304Sjkim : "+r"(ret)); ret; }) 44280304Sjkim# elif (defined(__i386) || defined(__i386__)) && !defined(I386_ONLY) 45280304Sjkim# define BSWAP8(x) ({ u32 lo=(u64)(x)>>32,hi=(x); \ 46280304Sjkim asm ("bswapl %0; bswapl %1" \ 47280304Sjkim : "+r"(hi),"+r"(lo)); \ 48280304Sjkim (u64)hi<<32|lo; }) 49280304Sjkim# define BSWAP4(x) ({ u32 ret=(x); \ 50280304Sjkim asm ("bswapl %0" \ 51280304Sjkim : "+r"(ret)); ret; }) 52280304Sjkim# elif (defined(__arm__) || defined(__arm)) && !defined(STRICT_ALIGNMENT) 53280304Sjkim# define BSWAP8(x) ({ u32 lo=(u64)(x)>>32,hi=(x); \ 54280304Sjkim asm ("rev %0,%0; rev %1,%1" \ 55280304Sjkim : "+r"(hi),"+r"(lo)); \ 56280304Sjkim (u64)hi<<32|lo; }) 57280304Sjkim# define BSWAP4(x) ({ u32 ret; \ 58280304Sjkim asm ("rev %0,%1" \ 59280304Sjkim : "=r"(ret) : "r"((u32)(x))); \ 60280304Sjkim ret; }) 61280304Sjkim# endif 62280304Sjkim# elif defined(_MSC_VER) 63280304Sjkim# if _MSC_VER>=1300 64280304Sjkim# pragma intrinsic(_byteswap_uint64,_byteswap_ulong) 65280304Sjkim# define BSWAP8(x) _byteswap_uint64((u64)(x)) 66280304Sjkim# define BSWAP4(x) _byteswap_ulong((u32)(x)) 67280304Sjkim# elif defined(_M_IX86) 68280304Sjkim__inline u32 _bswap4(u32 val) 69280304Sjkim{ 70280304Sjkim_asm mov eax, val _asm bswap eax} 71280304Sjkim# define BSWAP4(x) _bswap4(x) 72280304Sjkim# endif 73238384Sjkim# endif 74238384Sjkim#endif 75238384Sjkim#if defined(BSWAP4) && !defined(STRICT_ALIGNMENT) 76280304Sjkim# define GETU32(p) BSWAP4(*(const u32 *)(p)) 77280304Sjkim# define PUTU32(p,v) *(u32 *)(p) = BSWAP4(v) 78238384Sjkim#else 79280304Sjkim# define GETU32(p) ((u32)(p)[0]<<24|(u32)(p)[1]<<16|(u32)(p)[2]<<8|(u32)(p)[3]) 80280304Sjkim# define PUTU32(p,v) ((p)[0]=(u8)((v)>>24),(p)[1]=(u8)((v)>>16),(p)[2]=(u8)((v)>>8),(p)[3]=(u8)(v)) 81238384Sjkim#endif 82280304Sjkim/*- GCM definitions */ typedef struct { 83280304Sjkim u64 hi, lo; 84280304Sjkim} u128; 85238384Sjkim 86280304Sjkim#ifdef TABLE_BITS 87280304Sjkim# undef TABLE_BITS 88238384Sjkim#endif 89238384Sjkim/* 90238384Sjkim * Even though permitted values for TABLE_BITS are 8, 4 and 1, it should 91238384Sjkim * never be set to 8 [or 1]. For further information see gcm128.c. 92238384Sjkim */ 93280304Sjkim#define TABLE_BITS 4 94238384Sjkim 95238384Sjkimstruct gcm128_context { 96280304Sjkim /* Following 6 names follow names in GCM specification */ 97280304Sjkim union { 98280304Sjkim u64 u[2]; 99280304Sjkim u32 d[4]; 100280304Sjkim u8 c[16]; 101280304Sjkim size_t t[16 / sizeof(size_t)]; 102280304Sjkim } Yi, EKi, EK0, len, Xi, H; 103280304Sjkim /* 104280304Sjkim * Relative position of Xi, H and pre-computed Htable is used in some 105280304Sjkim * assembler modules, i.e. don't change the order! 106280304Sjkim */ 107238384Sjkim#if TABLE_BITS==8 108280304Sjkim u128 Htable[256]; 109238384Sjkim#else 110280304Sjkim u128 Htable[16]; 111280304Sjkim void (*gmult) (u64 Xi[2], const u128 Htable[16]); 112280304Sjkim void (*ghash) (u64 Xi[2], const u128 Htable[16], const u8 *inp, 113280304Sjkim size_t len); 114238384Sjkim#endif 115280304Sjkim unsigned int mres, ares; 116280304Sjkim block128_f block; 117280304Sjkim void *key; 118238384Sjkim}; 119238384Sjkim 120238384Sjkimstruct xts128_context { 121280304Sjkim void *key1, *key2; 122280304Sjkim block128_f block1, block2; 123238384Sjkim}; 124238384Sjkim 125238384Sjkimstruct ccm128_context { 126280304Sjkim union { 127280304Sjkim u64 u[2]; 128280304Sjkim u8 c[16]; 129280304Sjkim } nonce, cmac; 130280304Sjkim u64 blocks; 131280304Sjkim block128_f block; 132280304Sjkim void *key; 133238384Sjkim}; 134