1392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom/* ==================================================================== 2392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * Copyright (c) 2010 The OpenSSL Project. All rights reserved. 3392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * 4392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * Redistribution and use is governed by OpenSSL license. 5392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * ==================================================================== 6392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom */ 7392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 8392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#include <openssl/modes.h> 9392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 10392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 11392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__) 12392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromtypedef __int64 i64; 13392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromtypedef unsigned __int64 u64; 14392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#define U64(C) C##UI64 15392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#elif defined(__arch64__) 16392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromtypedef long i64; 17392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromtypedef unsigned long u64; 18392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#define U64(C) C##UL 19392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#else 20392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromtypedef long long i64; 21392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromtypedef unsigned long long u64; 22392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#define U64(C) C##ULL 23392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif 24392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 25392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromtypedef unsigned int u32; 26392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromtypedef unsigned char u8; 27392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 28392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#define STRICT_ALIGNMENT 1 29392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#if defined(__i386) || defined(__i386__) || \ 30392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom defined(__x86_64) || defined(__x86_64__) || \ 31392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64) || \ 32392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom defined(__s390__) || defined(__s390x__) || \ 33392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ( (defined(__arm__) || defined(__arm)) && \ 34392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom (defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || \ 35392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__)) ) 36392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom# undef STRICT_ALIGNMENT 37392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif 38392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 39392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#if !defined(PEDANTIC) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) 40392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#if defined(__GNUC__) && __GNUC__>=2 41392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom# if defined(__x86_64) || defined(__x86_64__) 42392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom# define BSWAP8(x) ({ u64 ret=(x); \ 43392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom asm ("bswapq %0" \ 44392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom : "+r"(ret)); ret; }) 45392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom# define BSWAP4(x) ({ u32 ret=(x); \ 46392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom asm ("bswapl %0" \ 47392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom : "+r"(ret)); ret; }) 48a1a5710c055e139ea00e785f9eb55b3af3e4dab1Brian Carlstrom# elif (defined(__i386) || defined(__i386__)) && !defined(I386_ONLY) 49392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom# define BSWAP8(x) ({ u32 lo=(u64)(x)>>32,hi=(x); \ 50392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom asm ("bswapl %0; bswapl %1" \ 51392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom : "+r"(hi),"+r"(lo)); \ 52392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom (u64)hi<<32|lo; }) 53392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom# define BSWAP4(x) ({ u32 ret=(x); \ 54392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom asm ("bswapl %0" \ 55392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom : "+r"(ret)); ret; }) 56392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom# elif (defined(__arm__) || defined(__arm)) && !defined(STRICT_ALIGNMENT) 57392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom# define BSWAP8(x) ({ u32 lo=(u64)(x)>>32,hi=(x); \ 58392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom asm ("rev %0,%0; rev %1,%1" \ 59392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom : "+r"(hi),"+r"(lo)); \ 60392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom (u64)hi<<32|lo; }) 61392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom# define BSWAP4(x) ({ u32 ret; \ 62392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom asm ("rev %0,%1" \ 63392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom : "=r"(ret) : "r"((u32)(x))); \ 64392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom ret; }) 65392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom# endif 66392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#elif defined(_MSC_VER) 67392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom# if _MSC_VER>=1300 68392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom# pragma intrinsic(_byteswap_uint64,_byteswap_ulong) 69392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom# define BSWAP8(x) _byteswap_uint64((u64)(x)) 70392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom# define BSWAP4(x) _byteswap_ulong((u32)(x)) 71392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom# elif defined(_M_IX86) 72392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom __inline u32 _bswap4(u32 val) { 73392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom _asm mov eax,val 74392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom _asm bswap eax 75392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom } 76392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom# define BSWAP4(x) _bswap4(x) 77392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom# endif 78392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif 79392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif 80392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 81392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#if defined(BSWAP4) && !defined(STRICT_ALIGNMENT) 82392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#define GETU32(p) BSWAP4(*(const u32 *)(p)) 83392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#define PUTU32(p,v) *(u32 *)(p) = BSWAP4(v) 84392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#else 85392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#define GETU32(p) ((u32)(p)[0]<<24|(u32)(p)[1]<<16|(u32)(p)[2]<<8|(u32)(p)[3]) 86392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#define PUTU32(p,v) ((p)[0]=(u8)((v)>>24),(p)[1]=(u8)((v)>>16),(p)[2]=(u8)((v)>>8),(p)[3]=(u8)(v)) 87392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif 88392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 89392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom/* GCM definitions */ 90392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 91392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromtypedef struct { u64 hi,lo; } u128; 92392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 93392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifdef TABLE_BITS 94392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#undef TABLE_BITS 95392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif 96392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom/* 97392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * Even though permitted values for TABLE_BITS are 8, 4 and 1, it should 98392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * never be set to 8 [or 1]. For further information see gcm128.c. 99392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom */ 100392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#define TABLE_BITS 4 101392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 102392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstruct gcm128_context { 103392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom /* Following 6 names follow names in GCM specification */ 104392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom union { u64 u[2]; u32 d[4]; u8 c[16]; } Yi,EKi,EK0,len, 105392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom Xi,H; 106392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom /* Relative position of Xi, H and pre-computed Htable is used 107392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * in some assembler modules, i.e. don't change the order! */ 108392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#if TABLE_BITS==8 109392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom u128 Htable[256]; 110392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#else 111392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom u128 Htable[16]; 112392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom void (*gmult)(u64 Xi[2],const u128 Htable[16]); 113392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom void (*ghash)(u64 Xi[2],const u128 Htable[16],const u8 *inp,size_t len); 114392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif 115392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom unsigned int mres, ares; 116392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom block128_f block; 117392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom void *key; 118392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom}; 119392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 120392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstruct xts128_context { 121392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom void *key1, *key2; 122392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom block128_f block1,block2; 123392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom}; 124392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 125392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstruct ccm128_context { 126392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom union { u64 u[2]; u8 c[16]; } nonce, cmac; 127392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom u64 blocks; 128392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom block128_f block; 129392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom void *key; 130392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom}; 131392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 132