1238384Sjkim/* ==================================================================== 2238384Sjkim * Copyright (c) 2010 The OpenSSL Project. All rights reserved. 3238384Sjkim * 4238384Sjkim * Redistribution and use in source and binary forms, with or without 5238384Sjkim * modification, are permitted provided that the following conditions 6238384Sjkim * are met: 7238384Sjkim * 8238384Sjkim * 1. Redistributions of source code must retain the above copyright 9280304Sjkim * notice, this list of conditions and the following disclaimer. 10238384Sjkim * 11238384Sjkim * 2. Redistributions in binary form must reproduce the above copyright 12238384Sjkim * notice, this list of conditions and the following disclaimer in 13238384Sjkim * the documentation and/or other materials provided with the 14238384Sjkim * distribution. 15238384Sjkim * 16238384Sjkim * 3. All advertising materials mentioning features or use of this 17238384Sjkim * software must display the following acknowledgment: 18238384Sjkim * "This product includes software developed by the OpenSSL Project 19238384Sjkim * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 20238384Sjkim * 21238384Sjkim * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 22238384Sjkim * endorse or promote products derived from this software without 23238384Sjkim * prior written permission. For written permission, please contact 24238384Sjkim * openssl-core@openssl.org. 25238384Sjkim * 26238384Sjkim * 5. Products derived from this software may not be called "OpenSSL" 27238384Sjkim * nor may "OpenSSL" appear in their names without prior written 28238384Sjkim * permission of the OpenSSL Project. 29238384Sjkim * 30238384Sjkim * 6. Redistributions of any form whatsoever must retain the following 31238384Sjkim * acknowledgment: 32238384Sjkim * "This product includes software developed by the OpenSSL Project 33238384Sjkim * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 34238384Sjkim * 35238384Sjkim * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 36238384Sjkim * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 37238384Sjkim * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 38238384Sjkim * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 39238384Sjkim * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 40238384Sjkim * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 41238384Sjkim * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 42238384Sjkim * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 43238384Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 44238384Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 45238384Sjkim * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 46238384Sjkim * OF THE POSSIBILITY OF SUCH DAMAGE. 47238384Sjkim * ==================================================================== 48238384Sjkim */ 49238384Sjkim 50238384Sjkim#define OPENSSL_FIPSAPI 51238384Sjkim 52238384Sjkim#include <openssl/crypto.h> 53238384Sjkim#include "modes_lcl.h" 54238384Sjkim#include <string.h> 55238384Sjkim 56238384Sjkim#ifndef MODES_DEBUG 57238384Sjkim# ifndef NDEBUG 58238384Sjkim# define NDEBUG 59238384Sjkim# endif 60238384Sjkim#endif 61238384Sjkim#include <assert.h> 62238384Sjkim 63238384Sjkim#if defined(BSWAP4) && defined(STRICT_ALIGNMENT) 64238384Sjkim/* redefine, because alignment is ensured */ 65280304Sjkim# undef GETU32 66280304Sjkim# define GETU32(p) BSWAP4(*(const u32 *)(p)) 67280304Sjkim# undef PUTU32 68280304Sjkim# define PUTU32(p,v) *(u32 *)(p) = BSWAP4(v) 69238384Sjkim#endif 70238384Sjkim 71280304Sjkim#define PACK(s) ((size_t)(s)<<(sizeof(size_t)*8-16)) 72280304Sjkim#define REDUCE1BIT(V) do { \ 73280304Sjkim if (sizeof(size_t)==8) { \ 74280304Sjkim u64 T = U64(0xe100000000000000) & (0-(V.lo&1)); \ 75280304Sjkim V.lo = (V.hi<<63)|(V.lo>>1); \ 76280304Sjkim V.hi = (V.hi>>1 )^T; \ 77280304Sjkim } \ 78280304Sjkim else { \ 79280304Sjkim u32 T = 0xe1000000U & (0-(u32)(V.lo&1)); \ 80280304Sjkim V.lo = (V.hi<<63)|(V.lo>>1); \ 81280304Sjkim V.hi = (V.hi>>1 )^((u64)T<<32); \ 82280304Sjkim } \ 83238384Sjkim} while(0) 84238384Sjkim 85280304Sjkim/*- 86238384Sjkim * Even though permitted values for TABLE_BITS are 8, 4 and 1, it should 87238384Sjkim * never be set to 8. 8 is effectively reserved for testing purposes. 88238384Sjkim * TABLE_BITS>1 are lookup-table-driven implementations referred to as 89238384Sjkim * "Shoup's" in GCM specification. In other words OpenSSL does not cover 90238384Sjkim * whole spectrum of possible table driven implementations. Why? In 91238384Sjkim * non-"Shoup's" case memory access pattern is segmented in such manner, 92238384Sjkim * that it's trivial to see that cache timing information can reveal 93238384Sjkim * fair portion of intermediate hash value. Given that ciphertext is 94238384Sjkim * always available to attacker, it's possible for him to attempt to 95238384Sjkim * deduce secret parameter H and if successful, tamper with messages 96238384Sjkim * [which is nothing but trivial in CTR mode]. In "Shoup's" case it's 97238384Sjkim * not as trivial, but there is no reason to believe that it's resistant 98238384Sjkim * to cache-timing attack. And the thing about "8-bit" implementation is 99238384Sjkim * that it consumes 16 (sixteen) times more memory, 4KB per individual 100238384Sjkim * key + 1KB shared. Well, on pros side it should be twice as fast as 101238384Sjkim * "4-bit" version. And for gcc-generated x86[_64] code, "8-bit" version 102238384Sjkim * was observed to run ~75% faster, closer to 100% for commercial 103238384Sjkim * compilers... Yet "4-bit" procedure is preferred, because it's 104238384Sjkim * believed to provide better security-performance balance and adequate 105238384Sjkim * all-round performance. "All-round" refers to things like: 106238384Sjkim * 107238384Sjkim * - shorter setup time effectively improves overall timing for 108238384Sjkim * handling short messages; 109238384Sjkim * - larger table allocation can become unbearable because of VM 110238384Sjkim * subsystem penalties (for example on Windows large enough free 111238384Sjkim * results in VM working set trimming, meaning that consequent 112238384Sjkim * malloc would immediately incur working set expansion); 113238384Sjkim * - larger table has larger cache footprint, which can affect 114238384Sjkim * performance of other code paths (not necessarily even from same 115238384Sjkim * thread in Hyper-Threading world); 116238384Sjkim * 117238384Sjkim * Value of 1 is not appropriate for performance reasons. 118238384Sjkim */ 119280304Sjkim#if TABLE_BITS==8 120238384Sjkim 121238384Sjkimstatic void gcm_init_8bit(u128 Htable[256], u64 H[2]) 122238384Sjkim{ 123280304Sjkim int i, j; 124280304Sjkim u128 V; 125238384Sjkim 126280304Sjkim Htable[0].hi = 0; 127280304Sjkim Htable[0].lo = 0; 128280304Sjkim V.hi = H[0]; 129280304Sjkim V.lo = H[1]; 130238384Sjkim 131280304Sjkim for (Htable[128] = V, i = 64; i > 0; i >>= 1) { 132280304Sjkim REDUCE1BIT(V); 133280304Sjkim Htable[i] = V; 134280304Sjkim } 135238384Sjkim 136280304Sjkim for (i = 2; i < 256; i <<= 1) { 137280304Sjkim u128 *Hi = Htable + i, H0 = *Hi; 138280304Sjkim for (j = 1; j < i; ++j) { 139280304Sjkim Hi[j].hi = H0.hi ^ Htable[j].hi; 140280304Sjkim Hi[j].lo = H0.lo ^ Htable[j].lo; 141280304Sjkim } 142280304Sjkim } 143238384Sjkim} 144238384Sjkim 145238384Sjkimstatic void gcm_gmult_8bit(u64 Xi[2], const u128 Htable[256]) 146238384Sjkim{ 147280304Sjkim u128 Z = { 0, 0 }; 148280304Sjkim const u8 *xi = (const u8 *)Xi + 15; 149280304Sjkim size_t rem, n = *xi; 150280304Sjkim const union { 151280304Sjkim long one; 152280304Sjkim char little; 153280304Sjkim } is_endian = { 154280304Sjkim 1 155280304Sjkim }; 156280304Sjkim static const size_t rem_8bit[256] = { 157280304Sjkim PACK(0x0000), PACK(0x01C2), PACK(0x0384), PACK(0x0246), 158280304Sjkim PACK(0x0708), PACK(0x06CA), PACK(0x048C), PACK(0x054E), 159280304Sjkim PACK(0x0E10), PACK(0x0FD2), PACK(0x0D94), PACK(0x0C56), 160280304Sjkim PACK(0x0918), PACK(0x08DA), PACK(0x0A9C), PACK(0x0B5E), 161280304Sjkim PACK(0x1C20), PACK(0x1DE2), PACK(0x1FA4), PACK(0x1E66), 162280304Sjkim PACK(0x1B28), PACK(0x1AEA), PACK(0x18AC), PACK(0x196E), 163280304Sjkim PACK(0x1230), PACK(0x13F2), PACK(0x11B4), PACK(0x1076), 164280304Sjkim PACK(0x1538), PACK(0x14FA), PACK(0x16BC), PACK(0x177E), 165280304Sjkim PACK(0x3840), PACK(0x3982), PACK(0x3BC4), PACK(0x3A06), 166280304Sjkim PACK(0x3F48), PACK(0x3E8A), PACK(0x3CCC), PACK(0x3D0E), 167280304Sjkim PACK(0x3650), PACK(0x3792), PACK(0x35D4), PACK(0x3416), 168280304Sjkim PACK(0x3158), PACK(0x309A), PACK(0x32DC), PACK(0x331E), 169280304Sjkim PACK(0x2460), PACK(0x25A2), PACK(0x27E4), PACK(0x2626), 170280304Sjkim PACK(0x2368), PACK(0x22AA), PACK(0x20EC), PACK(0x212E), 171280304Sjkim PACK(0x2A70), PACK(0x2BB2), PACK(0x29F4), PACK(0x2836), 172280304Sjkim PACK(0x2D78), PACK(0x2CBA), PACK(0x2EFC), PACK(0x2F3E), 173280304Sjkim PACK(0x7080), PACK(0x7142), PACK(0x7304), PACK(0x72C6), 174280304Sjkim PACK(0x7788), PACK(0x764A), PACK(0x740C), PACK(0x75CE), 175280304Sjkim PACK(0x7E90), PACK(0x7F52), PACK(0x7D14), PACK(0x7CD6), 176280304Sjkim PACK(0x7998), PACK(0x785A), PACK(0x7A1C), PACK(0x7BDE), 177280304Sjkim PACK(0x6CA0), PACK(0x6D62), PACK(0x6F24), PACK(0x6EE6), 178280304Sjkim PACK(0x6BA8), PACK(0x6A6A), PACK(0x682C), PACK(0x69EE), 179280304Sjkim PACK(0x62B0), PACK(0x6372), PACK(0x6134), PACK(0x60F6), 180280304Sjkim PACK(0x65B8), PACK(0x647A), PACK(0x663C), PACK(0x67FE), 181280304Sjkim PACK(0x48C0), PACK(0x4902), PACK(0x4B44), PACK(0x4A86), 182280304Sjkim PACK(0x4FC8), PACK(0x4E0A), PACK(0x4C4C), PACK(0x4D8E), 183280304Sjkim PACK(0x46D0), PACK(0x4712), PACK(0x4554), PACK(0x4496), 184280304Sjkim PACK(0x41D8), PACK(0x401A), PACK(0x425C), PACK(0x439E), 185280304Sjkim PACK(0x54E0), PACK(0x5522), PACK(0x5764), PACK(0x56A6), 186280304Sjkim PACK(0x53E8), PACK(0x522A), PACK(0x506C), PACK(0x51AE), 187280304Sjkim PACK(0x5AF0), PACK(0x5B32), PACK(0x5974), PACK(0x58B6), 188280304Sjkim PACK(0x5DF8), PACK(0x5C3A), PACK(0x5E7C), PACK(0x5FBE), 189280304Sjkim PACK(0xE100), PACK(0xE0C2), PACK(0xE284), PACK(0xE346), 190280304Sjkim PACK(0xE608), PACK(0xE7CA), PACK(0xE58C), PACK(0xE44E), 191280304Sjkim PACK(0xEF10), PACK(0xEED2), PACK(0xEC94), PACK(0xED56), 192280304Sjkim PACK(0xE818), PACK(0xE9DA), PACK(0xEB9C), PACK(0xEA5E), 193280304Sjkim PACK(0xFD20), PACK(0xFCE2), PACK(0xFEA4), PACK(0xFF66), 194280304Sjkim PACK(0xFA28), PACK(0xFBEA), PACK(0xF9AC), PACK(0xF86E), 195280304Sjkim PACK(0xF330), PACK(0xF2F2), PACK(0xF0B4), PACK(0xF176), 196280304Sjkim PACK(0xF438), PACK(0xF5FA), PACK(0xF7BC), PACK(0xF67E), 197280304Sjkim PACK(0xD940), PACK(0xD882), PACK(0xDAC4), PACK(0xDB06), 198280304Sjkim PACK(0xDE48), PACK(0xDF8A), PACK(0xDDCC), PACK(0xDC0E), 199280304Sjkim PACK(0xD750), PACK(0xD692), PACK(0xD4D4), PACK(0xD516), 200280304Sjkim PACK(0xD058), PACK(0xD19A), PACK(0xD3DC), PACK(0xD21E), 201280304Sjkim PACK(0xC560), PACK(0xC4A2), PACK(0xC6E4), PACK(0xC726), 202280304Sjkim PACK(0xC268), PACK(0xC3AA), PACK(0xC1EC), PACK(0xC02E), 203280304Sjkim PACK(0xCB70), PACK(0xCAB2), PACK(0xC8F4), PACK(0xC936), 204280304Sjkim PACK(0xCC78), PACK(0xCDBA), PACK(0xCFFC), PACK(0xCE3E), 205280304Sjkim PACK(0x9180), PACK(0x9042), PACK(0x9204), PACK(0x93C6), 206280304Sjkim PACK(0x9688), PACK(0x974A), PACK(0x950C), PACK(0x94CE), 207280304Sjkim PACK(0x9F90), PACK(0x9E52), PACK(0x9C14), PACK(0x9DD6), 208280304Sjkim PACK(0x9898), PACK(0x995A), PACK(0x9B1C), PACK(0x9ADE), 209280304Sjkim PACK(0x8DA0), PACK(0x8C62), PACK(0x8E24), PACK(0x8FE6), 210280304Sjkim PACK(0x8AA8), PACK(0x8B6A), PACK(0x892C), PACK(0x88EE), 211280304Sjkim PACK(0x83B0), PACK(0x8272), PACK(0x8034), PACK(0x81F6), 212280304Sjkim PACK(0x84B8), PACK(0x857A), PACK(0x873C), PACK(0x86FE), 213280304Sjkim PACK(0xA9C0), PACK(0xA802), PACK(0xAA44), PACK(0xAB86), 214280304Sjkim PACK(0xAEC8), PACK(0xAF0A), PACK(0xAD4C), PACK(0xAC8E), 215280304Sjkim PACK(0xA7D0), PACK(0xA612), PACK(0xA454), PACK(0xA596), 216280304Sjkim PACK(0xA0D8), PACK(0xA11A), PACK(0xA35C), PACK(0xA29E), 217280304Sjkim PACK(0xB5E0), PACK(0xB422), PACK(0xB664), PACK(0xB7A6), 218280304Sjkim PACK(0xB2E8), PACK(0xB32A), PACK(0xB16C), PACK(0xB0AE), 219280304Sjkim PACK(0xBBF0), PACK(0xBA32), PACK(0xB874), PACK(0xB9B6), 220280304Sjkim PACK(0xBCF8), PACK(0xBD3A), PACK(0xBF7C), PACK(0xBEBE) 221280304Sjkim }; 222238384Sjkim 223280304Sjkim while (1) { 224280304Sjkim Z.hi ^= Htable[n].hi; 225280304Sjkim Z.lo ^= Htable[n].lo; 226238384Sjkim 227280304Sjkim if ((u8 *)Xi == xi) 228280304Sjkim break; 229238384Sjkim 230280304Sjkim n = *(--xi); 231238384Sjkim 232280304Sjkim rem = (size_t)Z.lo & 0xff; 233280304Sjkim Z.lo = (Z.hi << 56) | (Z.lo >> 8); 234280304Sjkim Z.hi = (Z.hi >> 8); 235280304Sjkim if (sizeof(size_t) == 8) 236280304Sjkim Z.hi ^= rem_8bit[rem]; 237280304Sjkim else 238280304Sjkim Z.hi ^= (u64)rem_8bit[rem] << 32; 239280304Sjkim } 240238384Sjkim 241280304Sjkim if (is_endian.little) { 242280304Sjkim# ifdef BSWAP8 243280304Sjkim Xi[0] = BSWAP8(Z.hi); 244280304Sjkim Xi[1] = BSWAP8(Z.lo); 245280304Sjkim# else 246280304Sjkim u8 *p = (u8 *)Xi; 247280304Sjkim u32 v; 248280304Sjkim v = (u32)(Z.hi >> 32); 249280304Sjkim PUTU32(p, v); 250280304Sjkim v = (u32)(Z.hi); 251280304Sjkim PUTU32(p + 4, v); 252280304Sjkim v = (u32)(Z.lo >> 32); 253280304Sjkim PUTU32(p + 8, v); 254280304Sjkim v = (u32)(Z.lo); 255280304Sjkim PUTU32(p + 12, v); 256280304Sjkim# endif 257280304Sjkim } else { 258280304Sjkim Xi[0] = Z.hi; 259280304Sjkim Xi[1] = Z.lo; 260280304Sjkim } 261238384Sjkim} 262238384Sjkim 263280304Sjkim# define GCM_MUL(ctx,Xi) gcm_gmult_8bit(ctx->Xi.u,ctx->Htable) 264238384Sjkim 265280304Sjkim#elif TABLE_BITS==4 266280304Sjkim 267238384Sjkimstatic void gcm_init_4bit(u128 Htable[16], u64 H[2]) 268238384Sjkim{ 269280304Sjkim u128 V; 270280304Sjkim# if defined(OPENSSL_SMALL_FOOTPRINT) 271280304Sjkim int i; 272280304Sjkim# endif 273238384Sjkim 274280304Sjkim Htable[0].hi = 0; 275280304Sjkim Htable[0].lo = 0; 276280304Sjkim V.hi = H[0]; 277280304Sjkim V.lo = H[1]; 278238384Sjkim 279280304Sjkim# if defined(OPENSSL_SMALL_FOOTPRINT) 280280304Sjkim for (Htable[8] = V, i = 4; i > 0; i >>= 1) { 281280304Sjkim REDUCE1BIT(V); 282280304Sjkim Htable[i] = V; 283280304Sjkim } 284238384Sjkim 285280304Sjkim for (i = 2; i < 16; i <<= 1) { 286280304Sjkim u128 *Hi = Htable + i; 287280304Sjkim int j; 288280304Sjkim for (V = *Hi, j = 1; j < i; ++j) { 289280304Sjkim Hi[j].hi = V.hi ^ Htable[j].hi; 290280304Sjkim Hi[j].lo = V.lo ^ Htable[j].lo; 291280304Sjkim } 292280304Sjkim } 293280304Sjkim# else 294280304Sjkim Htable[8] = V; 295280304Sjkim REDUCE1BIT(V); 296280304Sjkim Htable[4] = V; 297280304Sjkim REDUCE1BIT(V); 298280304Sjkim Htable[2] = V; 299280304Sjkim REDUCE1BIT(V); 300280304Sjkim Htable[1] = V; 301280304Sjkim Htable[3].hi = V.hi ^ Htable[2].hi, Htable[3].lo = V.lo ^ Htable[2].lo; 302280304Sjkim V = Htable[4]; 303280304Sjkim Htable[5].hi = V.hi ^ Htable[1].hi, Htable[5].lo = V.lo ^ Htable[1].lo; 304280304Sjkim Htable[6].hi = V.hi ^ Htable[2].hi, Htable[6].lo = V.lo ^ Htable[2].lo; 305280304Sjkim Htable[7].hi = V.hi ^ Htable[3].hi, Htable[7].lo = V.lo ^ Htable[3].lo; 306280304Sjkim V = Htable[8]; 307280304Sjkim Htable[9].hi = V.hi ^ Htable[1].hi, Htable[9].lo = V.lo ^ Htable[1].lo; 308280304Sjkim Htable[10].hi = V.hi ^ Htable[2].hi, Htable[10].lo = V.lo ^ Htable[2].lo; 309280304Sjkim Htable[11].hi = V.hi ^ Htable[3].hi, Htable[11].lo = V.lo ^ Htable[3].lo; 310280304Sjkim Htable[12].hi = V.hi ^ Htable[4].hi, Htable[12].lo = V.lo ^ Htable[4].lo; 311280304Sjkim Htable[13].hi = V.hi ^ Htable[5].hi, Htable[13].lo = V.lo ^ Htable[5].lo; 312280304Sjkim Htable[14].hi = V.hi ^ Htable[6].hi, Htable[14].lo = V.lo ^ Htable[6].lo; 313280304Sjkim Htable[15].hi = V.hi ^ Htable[7].hi, Htable[15].lo = V.lo ^ Htable[7].lo; 314280304Sjkim# endif 315280304Sjkim# if defined(GHASH_ASM) && (defined(__arm__) || defined(__arm)) 316280304Sjkim /* 317280304Sjkim * ARM assembler expects specific dword order in Htable. 318280304Sjkim */ 319280304Sjkim { 320280304Sjkim int j; 321280304Sjkim const union { 322280304Sjkim long one; 323280304Sjkim char little; 324280304Sjkim } is_endian = { 325280304Sjkim 1 326280304Sjkim }; 327238384Sjkim 328280304Sjkim if (is_endian.little) 329280304Sjkim for (j = 0; j < 16; ++j) { 330280304Sjkim V = Htable[j]; 331280304Sjkim Htable[j].hi = V.lo; 332280304Sjkim Htable[j].lo = V.hi; 333280304Sjkim } else 334280304Sjkim for (j = 0; j < 16; ++j) { 335280304Sjkim V = Htable[j]; 336280304Sjkim Htable[j].hi = V.lo << 32 | V.lo >> 32; 337280304Sjkim Htable[j].lo = V.hi << 32 | V.hi >> 32; 338280304Sjkim } 339280304Sjkim } 340280304Sjkim# endif 341238384Sjkim} 342238384Sjkim 343280304Sjkim# ifndef GHASH_ASM 344238384Sjkimstatic const size_t rem_4bit[16] = { 345280304Sjkim PACK(0x0000), PACK(0x1C20), PACK(0x3840), PACK(0x2460), 346280304Sjkim PACK(0x7080), PACK(0x6CA0), PACK(0x48C0), PACK(0x54E0), 347280304Sjkim PACK(0xE100), PACK(0xFD20), PACK(0xD940), PACK(0xC560), 348280304Sjkim PACK(0x9180), PACK(0x8DA0), PACK(0xA9C0), PACK(0xB5E0) 349280304Sjkim}; 350238384Sjkim 351238384Sjkimstatic void gcm_gmult_4bit(u64 Xi[2], const u128 Htable[16]) 352238384Sjkim{ 353280304Sjkim u128 Z; 354280304Sjkim int cnt = 15; 355280304Sjkim size_t rem, nlo, nhi; 356280304Sjkim const union { 357280304Sjkim long one; 358280304Sjkim char little; 359280304Sjkim } is_endian = { 360280304Sjkim 1 361280304Sjkim }; 362238384Sjkim 363280304Sjkim nlo = ((const u8 *)Xi)[15]; 364280304Sjkim nhi = nlo >> 4; 365280304Sjkim nlo &= 0xf; 366238384Sjkim 367280304Sjkim Z.hi = Htable[nlo].hi; 368280304Sjkim Z.lo = Htable[nlo].lo; 369238384Sjkim 370280304Sjkim while (1) { 371280304Sjkim rem = (size_t)Z.lo & 0xf; 372280304Sjkim Z.lo = (Z.hi << 60) | (Z.lo >> 4); 373280304Sjkim Z.hi = (Z.hi >> 4); 374280304Sjkim if (sizeof(size_t) == 8) 375280304Sjkim Z.hi ^= rem_4bit[rem]; 376280304Sjkim else 377280304Sjkim Z.hi ^= (u64)rem_4bit[rem] << 32; 378238384Sjkim 379280304Sjkim Z.hi ^= Htable[nhi].hi; 380280304Sjkim Z.lo ^= Htable[nhi].lo; 381238384Sjkim 382280304Sjkim if (--cnt < 0) 383280304Sjkim break; 384238384Sjkim 385280304Sjkim nlo = ((const u8 *)Xi)[cnt]; 386280304Sjkim nhi = nlo >> 4; 387280304Sjkim nlo &= 0xf; 388238384Sjkim 389280304Sjkim rem = (size_t)Z.lo & 0xf; 390280304Sjkim Z.lo = (Z.hi << 60) | (Z.lo >> 4); 391280304Sjkim Z.hi = (Z.hi >> 4); 392280304Sjkim if (sizeof(size_t) == 8) 393280304Sjkim Z.hi ^= rem_4bit[rem]; 394280304Sjkim else 395280304Sjkim Z.hi ^= (u64)rem_4bit[rem] << 32; 396238384Sjkim 397280304Sjkim Z.hi ^= Htable[nlo].hi; 398280304Sjkim Z.lo ^= Htable[nlo].lo; 399280304Sjkim } 400238384Sjkim 401280304Sjkim if (is_endian.little) { 402280304Sjkim# ifdef BSWAP8 403280304Sjkim Xi[0] = BSWAP8(Z.hi); 404280304Sjkim Xi[1] = BSWAP8(Z.lo); 405280304Sjkim# else 406280304Sjkim u8 *p = (u8 *)Xi; 407280304Sjkim u32 v; 408280304Sjkim v = (u32)(Z.hi >> 32); 409280304Sjkim PUTU32(p, v); 410280304Sjkim v = (u32)(Z.hi); 411280304Sjkim PUTU32(p + 4, v); 412280304Sjkim v = (u32)(Z.lo >> 32); 413280304Sjkim PUTU32(p + 8, v); 414280304Sjkim v = (u32)(Z.lo); 415280304Sjkim PUTU32(p + 12, v); 416280304Sjkim# endif 417280304Sjkim } else { 418280304Sjkim Xi[0] = Z.hi; 419280304Sjkim Xi[1] = Z.lo; 420280304Sjkim } 421238384Sjkim} 422238384Sjkim 423280304Sjkim# if !defined(OPENSSL_SMALL_FOOTPRINT) 424238384Sjkim/* 425238384Sjkim * Streamed gcm_mult_4bit, see CRYPTO_gcm128_[en|de]crypt for 426238384Sjkim * details... Compiler-generated code doesn't seem to give any 427238384Sjkim * performance improvement, at least not on x86[_64]. It's here 428238384Sjkim * mostly as reference and a placeholder for possible future 429238384Sjkim * non-trivial optimization[s]... 430238384Sjkim */ 431280304Sjkimstatic void gcm_ghash_4bit(u64 Xi[2], const u128 Htable[16], 432280304Sjkim const u8 *inp, size_t len) 433238384Sjkim{ 434238384Sjkim u128 Z; 435238384Sjkim int cnt; 436238384Sjkim size_t rem, nlo, nhi; 437280304Sjkim const union { 438280304Sjkim long one; 439280304Sjkim char little; 440280304Sjkim } is_endian = { 441280304Sjkim 1 442280304Sjkim }; 443238384Sjkim 444280304Sjkim# if 1 445238384Sjkim do { 446280304Sjkim cnt = 15; 447280304Sjkim nlo = ((const u8 *)Xi)[15]; 448280304Sjkim nlo ^= inp[15]; 449280304Sjkim nhi = nlo >> 4; 450280304Sjkim nlo &= 0xf; 451238384Sjkim 452280304Sjkim Z.hi = Htable[nlo].hi; 453280304Sjkim Z.lo = Htable[nlo].lo; 454238384Sjkim 455280304Sjkim while (1) { 456280304Sjkim rem = (size_t)Z.lo & 0xf; 457280304Sjkim Z.lo = (Z.hi << 60) | (Z.lo >> 4); 458280304Sjkim Z.hi = (Z.hi >> 4); 459280304Sjkim if (sizeof(size_t) == 8) 460280304Sjkim Z.hi ^= rem_4bit[rem]; 461280304Sjkim else 462280304Sjkim Z.hi ^= (u64)rem_4bit[rem] << 32; 463238384Sjkim 464280304Sjkim Z.hi ^= Htable[nhi].hi; 465280304Sjkim Z.lo ^= Htable[nhi].lo; 466238384Sjkim 467280304Sjkim if (--cnt < 0) 468280304Sjkim break; 469238384Sjkim 470280304Sjkim nlo = ((const u8 *)Xi)[cnt]; 471280304Sjkim nlo ^= inp[cnt]; 472280304Sjkim nhi = nlo >> 4; 473280304Sjkim nlo &= 0xf; 474238384Sjkim 475280304Sjkim rem = (size_t)Z.lo & 0xf; 476280304Sjkim Z.lo = (Z.hi << 60) | (Z.lo >> 4); 477280304Sjkim Z.hi = (Z.hi >> 4); 478280304Sjkim if (sizeof(size_t) == 8) 479280304Sjkim Z.hi ^= rem_4bit[rem]; 480280304Sjkim else 481280304Sjkim Z.hi ^= (u64)rem_4bit[rem] << 32; 482238384Sjkim 483280304Sjkim Z.hi ^= Htable[nlo].hi; 484280304Sjkim Z.lo ^= Htable[nlo].lo; 485280304Sjkim } 486280304Sjkim# else 487238384Sjkim /* 488238384Sjkim * Extra 256+16 bytes per-key plus 512 bytes shared tables 489238384Sjkim * [should] give ~50% improvement... One could have PACK()-ed 490238384Sjkim * the rem_8bit even here, but the priority is to minimize 491238384Sjkim * cache footprint... 492280304Sjkim */ 493280304Sjkim u128 Hshr4[16]; /* Htable shifted right by 4 bits */ 494280304Sjkim u8 Hshl4[16]; /* Htable shifted left by 4 bits */ 495238384Sjkim static const unsigned short rem_8bit[256] = { 496280304Sjkim 0x0000, 0x01C2, 0x0384, 0x0246, 0x0708, 0x06CA, 0x048C, 0x054E, 497280304Sjkim 0x0E10, 0x0FD2, 0x0D94, 0x0C56, 0x0918, 0x08DA, 0x0A9C, 0x0B5E, 498280304Sjkim 0x1C20, 0x1DE2, 0x1FA4, 0x1E66, 0x1B28, 0x1AEA, 0x18AC, 0x196E, 499280304Sjkim 0x1230, 0x13F2, 0x11B4, 0x1076, 0x1538, 0x14FA, 0x16BC, 0x177E, 500280304Sjkim 0x3840, 0x3982, 0x3BC4, 0x3A06, 0x3F48, 0x3E8A, 0x3CCC, 0x3D0E, 501280304Sjkim 0x3650, 0x3792, 0x35D4, 0x3416, 0x3158, 0x309A, 0x32DC, 0x331E, 502280304Sjkim 0x2460, 0x25A2, 0x27E4, 0x2626, 0x2368, 0x22AA, 0x20EC, 0x212E, 503280304Sjkim 0x2A70, 0x2BB2, 0x29F4, 0x2836, 0x2D78, 0x2CBA, 0x2EFC, 0x2F3E, 504280304Sjkim 0x7080, 0x7142, 0x7304, 0x72C6, 0x7788, 0x764A, 0x740C, 0x75CE, 505280304Sjkim 0x7E90, 0x7F52, 0x7D14, 0x7CD6, 0x7998, 0x785A, 0x7A1C, 0x7BDE, 506280304Sjkim 0x6CA0, 0x6D62, 0x6F24, 0x6EE6, 0x6BA8, 0x6A6A, 0x682C, 0x69EE, 507280304Sjkim 0x62B0, 0x6372, 0x6134, 0x60F6, 0x65B8, 0x647A, 0x663C, 0x67FE, 508280304Sjkim 0x48C0, 0x4902, 0x4B44, 0x4A86, 0x4FC8, 0x4E0A, 0x4C4C, 0x4D8E, 509280304Sjkim 0x46D0, 0x4712, 0x4554, 0x4496, 0x41D8, 0x401A, 0x425C, 0x439E, 510280304Sjkim 0x54E0, 0x5522, 0x5764, 0x56A6, 0x53E8, 0x522A, 0x506C, 0x51AE, 511280304Sjkim 0x5AF0, 0x5B32, 0x5974, 0x58B6, 0x5DF8, 0x5C3A, 0x5E7C, 0x5FBE, 512280304Sjkim 0xE100, 0xE0C2, 0xE284, 0xE346, 0xE608, 0xE7CA, 0xE58C, 0xE44E, 513280304Sjkim 0xEF10, 0xEED2, 0xEC94, 0xED56, 0xE818, 0xE9DA, 0xEB9C, 0xEA5E, 514280304Sjkim 0xFD20, 0xFCE2, 0xFEA4, 0xFF66, 0xFA28, 0xFBEA, 0xF9AC, 0xF86E, 515280304Sjkim 0xF330, 0xF2F2, 0xF0B4, 0xF176, 0xF438, 0xF5FA, 0xF7BC, 0xF67E, 516280304Sjkim 0xD940, 0xD882, 0xDAC4, 0xDB06, 0xDE48, 0xDF8A, 0xDDCC, 0xDC0E, 517280304Sjkim 0xD750, 0xD692, 0xD4D4, 0xD516, 0xD058, 0xD19A, 0xD3DC, 0xD21E, 518280304Sjkim 0xC560, 0xC4A2, 0xC6E4, 0xC726, 0xC268, 0xC3AA, 0xC1EC, 0xC02E, 519280304Sjkim 0xCB70, 0xCAB2, 0xC8F4, 0xC936, 0xCC78, 0xCDBA, 0xCFFC, 0xCE3E, 520280304Sjkim 0x9180, 0x9042, 0x9204, 0x93C6, 0x9688, 0x974A, 0x950C, 0x94CE, 521280304Sjkim 0x9F90, 0x9E52, 0x9C14, 0x9DD6, 0x9898, 0x995A, 0x9B1C, 0x9ADE, 522280304Sjkim 0x8DA0, 0x8C62, 0x8E24, 0x8FE6, 0x8AA8, 0x8B6A, 0x892C, 0x88EE, 523280304Sjkim 0x83B0, 0x8272, 0x8034, 0x81F6, 0x84B8, 0x857A, 0x873C, 0x86FE, 524280304Sjkim 0xA9C0, 0xA802, 0xAA44, 0xAB86, 0xAEC8, 0xAF0A, 0xAD4C, 0xAC8E, 525280304Sjkim 0xA7D0, 0xA612, 0xA454, 0xA596, 0xA0D8, 0xA11A, 0xA35C, 0xA29E, 526280304Sjkim 0xB5E0, 0xB422, 0xB664, 0xB7A6, 0xB2E8, 0xB32A, 0xB16C, 0xB0AE, 527280304Sjkim 0xBBF0, 0xBA32, 0xB874, 0xB9B6, 0xBCF8, 0xBD3A, 0xBF7C, 0xBEBE 528280304Sjkim }; 529238384Sjkim /* 530238384Sjkim * This pre-processing phase slows down procedure by approximately 531238384Sjkim * same time as it makes each loop spin faster. In other words 532238384Sjkim * single block performance is approximately same as straightforward 533238384Sjkim * "4-bit" implementation, and then it goes only faster... 534238384Sjkim */ 535280304Sjkim for (cnt = 0; cnt < 16; ++cnt) { 536280304Sjkim Z.hi = Htable[cnt].hi; 537280304Sjkim Z.lo = Htable[cnt].lo; 538280304Sjkim Hshr4[cnt].lo = (Z.hi << 60) | (Z.lo >> 4); 539280304Sjkim Hshr4[cnt].hi = (Z.hi >> 4); 540280304Sjkim Hshl4[cnt] = (u8)(Z.lo << 4); 541238384Sjkim } 542238384Sjkim 543238384Sjkim do { 544280304Sjkim for (Z.lo = 0, Z.hi = 0, cnt = 15; cnt; --cnt) { 545280304Sjkim nlo = ((const u8 *)Xi)[cnt]; 546280304Sjkim nlo ^= inp[cnt]; 547280304Sjkim nhi = nlo >> 4; 548280304Sjkim nlo &= 0xf; 549238384Sjkim 550280304Sjkim Z.hi ^= Htable[nlo].hi; 551280304Sjkim Z.lo ^= Htable[nlo].lo; 552238384Sjkim 553280304Sjkim rem = (size_t)Z.lo & 0xff; 554238384Sjkim 555280304Sjkim Z.lo = (Z.hi << 56) | (Z.lo >> 8); 556280304Sjkim Z.hi = (Z.hi >> 8); 557238384Sjkim 558280304Sjkim Z.hi ^= Hshr4[nhi].hi; 559280304Sjkim Z.lo ^= Hshr4[nhi].lo; 560280304Sjkim Z.hi ^= (u64)rem_8bit[rem ^ Hshl4[nhi]] << 48; 561280304Sjkim } 562238384Sjkim 563280304Sjkim nlo = ((const u8 *)Xi)[0]; 564280304Sjkim nlo ^= inp[0]; 565280304Sjkim nhi = nlo >> 4; 566280304Sjkim nlo &= 0xf; 567238384Sjkim 568280304Sjkim Z.hi ^= Htable[nlo].hi; 569280304Sjkim Z.lo ^= Htable[nlo].lo; 570238384Sjkim 571280304Sjkim rem = (size_t)Z.lo & 0xf; 572238384Sjkim 573280304Sjkim Z.lo = (Z.hi << 60) | (Z.lo >> 4); 574280304Sjkim Z.hi = (Z.hi >> 4); 575238384Sjkim 576280304Sjkim Z.hi ^= Htable[nhi].hi; 577280304Sjkim Z.lo ^= Htable[nhi].lo; 578280304Sjkim Z.hi ^= ((u64)rem_8bit[rem << 4]) << 48; 579280304Sjkim# endif 580238384Sjkim 581280304Sjkim if (is_endian.little) { 582280304Sjkim# ifdef BSWAP8 583280304Sjkim Xi[0] = BSWAP8(Z.hi); 584280304Sjkim Xi[1] = BSWAP8(Z.lo); 585280304Sjkim# else 586280304Sjkim u8 *p = (u8 *)Xi; 587280304Sjkim u32 v; 588280304Sjkim v = (u32)(Z.hi >> 32); 589280304Sjkim PUTU32(p, v); 590280304Sjkim v = (u32)(Z.hi); 591280304Sjkim PUTU32(p + 4, v); 592280304Sjkim v = (u32)(Z.lo >> 32); 593280304Sjkim PUTU32(p + 8, v); 594280304Sjkim v = (u32)(Z.lo); 595280304Sjkim PUTU32(p + 12, v); 596280304Sjkim# endif 597280304Sjkim } else { 598280304Sjkim Xi[0] = Z.hi; 599280304Sjkim Xi[1] = Z.lo; 600280304Sjkim } 601280304Sjkim } while (inp += 16, len -= 16); 602238384Sjkim} 603280304Sjkim# endif 604280304Sjkim# else 605280304Sjkimvoid gcm_gmult_4bit(u64 Xi[2], const u128 Htable[16]); 606280304Sjkimvoid gcm_ghash_4bit(u64 Xi[2], const u128 Htable[16], const u8 *inp, 607280304Sjkim size_t len); 608280304Sjkim# endif 609238384Sjkim 610280304Sjkim# define GCM_MUL(ctx,Xi) gcm_gmult_4bit(ctx->Xi.u,ctx->Htable) 611280304Sjkim# if defined(GHASH_ASM) || !defined(OPENSSL_SMALL_FOOTPRINT) 612280304Sjkim# define GHASH(ctx,in,len) gcm_ghash_4bit((ctx)->Xi.u,(ctx)->Htable,in,len) 613280304Sjkim/* 614280304Sjkim * GHASH_CHUNK is "stride parameter" missioned to mitigate cache trashing 615280304Sjkim * effect. In other words idea is to hash data while it's still in L1 cache 616280304Sjkim * after encryption pass... 617280304Sjkim */ 618280304Sjkim# define GHASH_CHUNK (3*1024) 619280304Sjkim# endif 620238384Sjkim 621280304Sjkim#else /* TABLE_BITS */ 622238384Sjkim 623280304Sjkimstatic void gcm_gmult_1bit(u64 Xi[2], const u64 H[2]) 624238384Sjkim{ 625280304Sjkim u128 V, Z = { 0, 0 }; 626280304Sjkim long X; 627280304Sjkim int i, j; 628280304Sjkim const long *xi = (const long *)Xi; 629280304Sjkim const union { 630280304Sjkim long one; 631280304Sjkim char little; 632280304Sjkim } is_endian = { 633280304Sjkim 1 634280304Sjkim }; 635238384Sjkim 636280304Sjkim V.hi = H[0]; /* H is in host byte order, no byte swapping */ 637280304Sjkim V.lo = H[1]; 638238384Sjkim 639280304Sjkim for (j = 0; j < 16 / sizeof(long); ++j) { 640280304Sjkim if (is_endian.little) { 641280304Sjkim if (sizeof(long) == 8) { 642280304Sjkim# ifdef BSWAP8 643280304Sjkim X = (long)(BSWAP8(xi[j])); 644280304Sjkim# else 645280304Sjkim const u8 *p = (const u8 *)(xi + j); 646280304Sjkim X = (long)((u64)GETU32(p) << 32 | GETU32(p + 4)); 647280304Sjkim# endif 648280304Sjkim } else { 649280304Sjkim const u8 *p = (const u8 *)(xi + j); 650280304Sjkim X = (long)GETU32(p); 651280304Sjkim } 652280304Sjkim } else 653280304Sjkim X = xi[j]; 654238384Sjkim 655280304Sjkim for (i = 0; i < 8 * sizeof(long); ++i, X <<= 1) { 656280304Sjkim u64 M = (u64)(X >> (8 * sizeof(long) - 1)); 657280304Sjkim Z.hi ^= V.hi & M; 658280304Sjkim Z.lo ^= V.lo & M; 659238384Sjkim 660280304Sjkim REDUCE1BIT(V); 661280304Sjkim } 662280304Sjkim } 663238384Sjkim 664280304Sjkim if (is_endian.little) { 665280304Sjkim# ifdef BSWAP8 666280304Sjkim Xi[0] = BSWAP8(Z.hi); 667280304Sjkim Xi[1] = BSWAP8(Z.lo); 668280304Sjkim# else 669280304Sjkim u8 *p = (u8 *)Xi; 670280304Sjkim u32 v; 671280304Sjkim v = (u32)(Z.hi >> 32); 672280304Sjkim PUTU32(p, v); 673280304Sjkim v = (u32)(Z.hi); 674280304Sjkim PUTU32(p + 4, v); 675280304Sjkim v = (u32)(Z.lo >> 32); 676280304Sjkim PUTU32(p + 8, v); 677280304Sjkim v = (u32)(Z.lo); 678280304Sjkim PUTU32(p + 12, v); 679280304Sjkim# endif 680280304Sjkim } else { 681280304Sjkim Xi[0] = Z.hi; 682280304Sjkim Xi[1] = Z.lo; 683280304Sjkim } 684238384Sjkim} 685238384Sjkim 686280304Sjkim# define GCM_MUL(ctx,Xi) gcm_gmult_1bit(ctx->Xi.u,ctx->H.u) 687280304Sjkim 688238384Sjkim#endif 689238384Sjkim 690280304Sjkim#if TABLE_BITS==4 && defined(GHASH_ASM) 691280304Sjkim# if !defined(I386_ONLY) && \ 692280304Sjkim (defined(__i386) || defined(__i386__) || \ 693280304Sjkim defined(__x86_64) || defined(__x86_64__) || \ 694280304Sjkim defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64)) 695238384Sjkim# define GHASH_ASM_X86_OR_64 696238384Sjkim# define GCM_FUNCREF_4BIT 697238384Sjkimextern unsigned int OPENSSL_ia32cap_P[2]; 698238384Sjkim 699280304Sjkimvoid gcm_init_clmul(u128 Htable[16], const u64 Xi[2]); 700280304Sjkimvoid gcm_gmult_clmul(u64 Xi[2], const u128 Htable[16]); 701280304Sjkimvoid gcm_ghash_clmul(u64 Xi[2], const u128 Htable[16], const u8 *inp, 702280304Sjkim size_t len); 703238384Sjkim 704280304Sjkim# if defined(__i386) || defined(__i386__) || defined(_M_IX86) 705238384Sjkim# define GHASH_ASM_X86 706280304Sjkimvoid gcm_gmult_4bit_mmx(u64 Xi[2], const u128 Htable[16]); 707280304Sjkimvoid gcm_ghash_4bit_mmx(u64 Xi[2], const u128 Htable[16], const u8 *inp, 708280304Sjkim size_t len); 709238384Sjkim 710280304Sjkimvoid gcm_gmult_4bit_x86(u64 Xi[2], const u128 Htable[16]); 711280304Sjkimvoid gcm_ghash_4bit_x86(u64 Xi[2], const u128 Htable[16], const u8 *inp, 712280304Sjkim size_t len); 713238384Sjkim# endif 714238384Sjkim# elif defined(__arm__) || defined(__arm) 715238384Sjkim# include "arm_arch.h" 716238384Sjkim# if __ARM_ARCH__>=7 717238384Sjkim# define GHASH_ASM_ARM 718238384Sjkim# define GCM_FUNCREF_4BIT 719280304Sjkimvoid gcm_gmult_neon(u64 Xi[2], const u128 Htable[16]); 720280304Sjkimvoid gcm_ghash_neon(u64 Xi[2], const u128 Htable[16], const u8 *inp, 721280304Sjkim size_t len); 722238384Sjkim# endif 723238384Sjkim# endif 724238384Sjkim#endif 725238384Sjkim 726238384Sjkim#ifdef GCM_FUNCREF_4BIT 727238384Sjkim# undef GCM_MUL 728280304Sjkim# define GCM_MUL(ctx,Xi) (*gcm_gmult_p)(ctx->Xi.u,ctx->Htable) 729238384Sjkim# ifdef GHASH 730238384Sjkim# undef GHASH 731280304Sjkim# define GHASH(ctx,in,len) (*gcm_ghash_p)(ctx->Xi.u,ctx->Htable,in,len) 732238384Sjkim# endif 733238384Sjkim#endif 734238384Sjkim 735280304Sjkimvoid CRYPTO_gcm128_init(GCM128_CONTEXT *ctx, void *key, block128_f block) 736238384Sjkim{ 737280304Sjkim const union { 738280304Sjkim long one; 739280304Sjkim char little; 740280304Sjkim } is_endian = { 741280304Sjkim 1 742280304Sjkim }; 743238384Sjkim 744280304Sjkim memset(ctx, 0, sizeof(*ctx)); 745280304Sjkim ctx->block = block; 746280304Sjkim ctx->key = key; 747238384Sjkim 748280304Sjkim (*block) (ctx->H.c, ctx->H.c, key); 749238384Sjkim 750280304Sjkim if (is_endian.little) { 751280304Sjkim /* H is stored in host byte order */ 752238384Sjkim#ifdef BSWAP8 753280304Sjkim ctx->H.u[0] = BSWAP8(ctx->H.u[0]); 754280304Sjkim ctx->H.u[1] = BSWAP8(ctx->H.u[1]); 755238384Sjkim#else 756280304Sjkim u8 *p = ctx->H.c; 757280304Sjkim u64 hi, lo; 758280304Sjkim hi = (u64)GETU32(p) << 32 | GETU32(p + 4); 759280304Sjkim lo = (u64)GETU32(p + 8) << 32 | GETU32(p + 12); 760280304Sjkim ctx->H.u[0] = hi; 761280304Sjkim ctx->H.u[1] = lo; 762238384Sjkim#endif 763280304Sjkim } 764280304Sjkim#if TABLE_BITS==8 765280304Sjkim gcm_init_8bit(ctx->Htable, ctx->H.u); 766280304Sjkim#elif TABLE_BITS==4 767280304Sjkim# if defined(GHASH_ASM_X86_OR_64) 768280304Sjkim# if !defined(GHASH_ASM_X86) || defined(OPENSSL_IA32_SSE2) 769280304Sjkim if (OPENSSL_ia32cap_P[0] & (1 << 24) && /* check FXSR bit */ 770280304Sjkim OPENSSL_ia32cap_P[1] & (1 << 1)) { /* check PCLMULQDQ bit */ 771280304Sjkim gcm_init_clmul(ctx->Htable, ctx->H.u); 772280304Sjkim ctx->gmult = gcm_gmult_clmul; 773280304Sjkim ctx->ghash = gcm_ghash_clmul; 774280304Sjkim return; 775280304Sjkim } 776238384Sjkim# endif 777280304Sjkim gcm_init_4bit(ctx->Htable, ctx->H.u); 778280304Sjkim# if defined(GHASH_ASM_X86) /* x86 only */ 779280304Sjkim# if defined(OPENSSL_IA32_SSE2) 780280304Sjkim if (OPENSSL_ia32cap_P[0] & (1 << 25)) { /* check SSE bit */ 781238384Sjkim# else 782280304Sjkim if (OPENSSL_ia32cap_P[0] & (1 << 23)) { /* check MMX bit */ 783238384Sjkim# endif 784280304Sjkim ctx->gmult = gcm_gmult_4bit_mmx; 785280304Sjkim ctx->ghash = gcm_ghash_4bit_mmx; 786280304Sjkim } else { 787280304Sjkim ctx->gmult = gcm_gmult_4bit_x86; 788280304Sjkim ctx->ghash = gcm_ghash_4bit_x86; 789280304Sjkim } 790238384Sjkim# else 791280304Sjkim ctx->gmult = gcm_gmult_4bit; 792280304Sjkim ctx->ghash = gcm_ghash_4bit; 793238384Sjkim# endif 794280304Sjkim# elif defined(GHASH_ASM_ARM) 795280304Sjkim if (OPENSSL_armcap_P & ARMV7_NEON) { 796280304Sjkim ctx->gmult = gcm_gmult_neon; 797280304Sjkim ctx->ghash = gcm_ghash_neon; 798280304Sjkim } else { 799280304Sjkim gcm_init_4bit(ctx->Htable, ctx->H.u); 800280304Sjkim ctx->gmult = gcm_gmult_4bit; 801280304Sjkim ctx->ghash = gcm_ghash_4bit; 802280304Sjkim } 803238384Sjkim# else 804280304Sjkim gcm_init_4bit(ctx->Htable, ctx->H.u); 805238384Sjkim# endif 806238384Sjkim#endif 807238384Sjkim} 808238384Sjkim 809280304Sjkimvoid CRYPTO_gcm128_setiv(GCM128_CONTEXT *ctx, const unsigned char *iv, 810280304Sjkim size_t len) 811238384Sjkim{ 812280304Sjkim const union { 813280304Sjkim long one; 814280304Sjkim char little; 815280304Sjkim } is_endian = { 816280304Sjkim 1 817280304Sjkim }; 818280304Sjkim unsigned int ctr; 819238384Sjkim#ifdef GCM_FUNCREF_4BIT 820280304Sjkim void (*gcm_gmult_p) (u64 Xi[2], const u128 Htable[16]) = ctx->gmult; 821238384Sjkim#endif 822238384Sjkim 823280304Sjkim ctx->Yi.u[0] = 0; 824280304Sjkim ctx->Yi.u[1] = 0; 825280304Sjkim ctx->Xi.u[0] = 0; 826280304Sjkim ctx->Xi.u[1] = 0; 827280304Sjkim ctx->len.u[0] = 0; /* AAD length */ 828280304Sjkim ctx->len.u[1] = 0; /* message length */ 829280304Sjkim ctx->ares = 0; 830280304Sjkim ctx->mres = 0; 831238384Sjkim 832280304Sjkim if (len == 12) { 833280304Sjkim memcpy(ctx->Yi.c, iv, 12); 834280304Sjkim ctx->Yi.c[15] = 1; 835280304Sjkim ctr = 1; 836280304Sjkim } else { 837280304Sjkim size_t i; 838280304Sjkim u64 len0 = len; 839238384Sjkim 840280304Sjkim while (len >= 16) { 841280304Sjkim for (i = 0; i < 16; ++i) 842280304Sjkim ctx->Yi.c[i] ^= iv[i]; 843280304Sjkim GCM_MUL(ctx, Yi); 844280304Sjkim iv += 16; 845280304Sjkim len -= 16; 846280304Sjkim } 847280304Sjkim if (len) { 848280304Sjkim for (i = 0; i < len; ++i) 849280304Sjkim ctx->Yi.c[i] ^= iv[i]; 850280304Sjkim GCM_MUL(ctx, Yi); 851280304Sjkim } 852280304Sjkim len0 <<= 3; 853280304Sjkim if (is_endian.little) { 854238384Sjkim#ifdef BSWAP8 855280304Sjkim ctx->Yi.u[1] ^= BSWAP8(len0); 856238384Sjkim#else 857280304Sjkim ctx->Yi.c[8] ^= (u8)(len0 >> 56); 858280304Sjkim ctx->Yi.c[9] ^= (u8)(len0 >> 48); 859280304Sjkim ctx->Yi.c[10] ^= (u8)(len0 >> 40); 860280304Sjkim ctx->Yi.c[11] ^= (u8)(len0 >> 32); 861280304Sjkim ctx->Yi.c[12] ^= (u8)(len0 >> 24); 862280304Sjkim ctx->Yi.c[13] ^= (u8)(len0 >> 16); 863280304Sjkim ctx->Yi.c[14] ^= (u8)(len0 >> 8); 864280304Sjkim ctx->Yi.c[15] ^= (u8)(len0); 865238384Sjkim#endif 866280304Sjkim } else 867280304Sjkim ctx->Yi.u[1] ^= len0; 868238384Sjkim 869280304Sjkim GCM_MUL(ctx, Yi); 870238384Sjkim 871280304Sjkim if (is_endian.little) 872264331Sjkim#ifdef BSWAP4 873280304Sjkim ctr = BSWAP4(ctx->Yi.d[3]); 874264331Sjkim#else 875280304Sjkim ctr = GETU32(ctx->Yi.c + 12); 876264331Sjkim#endif 877280304Sjkim else 878280304Sjkim ctr = ctx->Yi.d[3]; 879280304Sjkim } 880238384Sjkim 881280304Sjkim (*ctx->block) (ctx->Yi.c, ctx->EK0.c, ctx->key); 882280304Sjkim ++ctr; 883280304Sjkim if (is_endian.little) 884264331Sjkim#ifdef BSWAP4 885280304Sjkim ctx->Yi.d[3] = BSWAP4(ctr); 886264331Sjkim#else 887280304Sjkim PUTU32(ctx->Yi.c + 12, ctr); 888264331Sjkim#endif 889280304Sjkim else 890280304Sjkim ctx->Yi.d[3] = ctr; 891238384Sjkim} 892238384Sjkim 893280304Sjkimint CRYPTO_gcm128_aad(GCM128_CONTEXT *ctx, const unsigned char *aad, 894280304Sjkim size_t len) 895238384Sjkim{ 896280304Sjkim size_t i; 897280304Sjkim unsigned int n; 898280304Sjkim u64 alen = ctx->len.u[0]; 899238384Sjkim#ifdef GCM_FUNCREF_4BIT 900280304Sjkim void (*gcm_gmult_p) (u64 Xi[2], const u128 Htable[16]) = ctx->gmult; 901238384Sjkim# ifdef GHASH 902280304Sjkim void (*gcm_ghash_p) (u64 Xi[2], const u128 Htable[16], 903280304Sjkim const u8 *inp, size_t len) = ctx->ghash; 904238384Sjkim# endif 905238384Sjkim#endif 906238384Sjkim 907280304Sjkim if (ctx->len.u[1]) 908280304Sjkim return -2; 909238384Sjkim 910280304Sjkim alen += len; 911280304Sjkim if (alen > (U64(1) << 61) || (sizeof(len) == 8 && alen < len)) 912280304Sjkim return -1; 913280304Sjkim ctx->len.u[0] = alen; 914238384Sjkim 915280304Sjkim n = ctx->ares; 916280304Sjkim if (n) { 917280304Sjkim while (n && len) { 918280304Sjkim ctx->Xi.c[n] ^= *(aad++); 919280304Sjkim --len; 920280304Sjkim n = (n + 1) % 16; 921280304Sjkim } 922280304Sjkim if (n == 0) 923280304Sjkim GCM_MUL(ctx, Xi); 924280304Sjkim else { 925280304Sjkim ctx->ares = n; 926280304Sjkim return 0; 927280304Sjkim } 928280304Sjkim } 929238384Sjkim#ifdef GHASH 930280304Sjkim if ((i = (len & (size_t)-16))) { 931280304Sjkim GHASH(ctx, aad, i); 932280304Sjkim aad += i; 933280304Sjkim len -= i; 934280304Sjkim } 935238384Sjkim#else 936280304Sjkim while (len >= 16) { 937280304Sjkim for (i = 0; i < 16; ++i) 938280304Sjkim ctx->Xi.c[i] ^= aad[i]; 939280304Sjkim GCM_MUL(ctx, Xi); 940280304Sjkim aad += 16; 941280304Sjkim len -= 16; 942280304Sjkim } 943238384Sjkim#endif 944280304Sjkim if (len) { 945280304Sjkim n = (unsigned int)len; 946280304Sjkim for (i = 0; i < len; ++i) 947280304Sjkim ctx->Xi.c[i] ^= aad[i]; 948280304Sjkim } 949238384Sjkim 950280304Sjkim ctx->ares = n; 951280304Sjkim return 0; 952238384Sjkim} 953238384Sjkim 954238384Sjkimint CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx, 955280304Sjkim const unsigned char *in, unsigned char *out, 956280304Sjkim size_t len) 957238384Sjkim{ 958280304Sjkim const union { 959280304Sjkim long one; 960280304Sjkim char little; 961280304Sjkim } is_endian = { 962280304Sjkim 1 963280304Sjkim }; 964280304Sjkim unsigned int n, ctr; 965280304Sjkim size_t i; 966280304Sjkim u64 mlen = ctx->len.u[1]; 967280304Sjkim block128_f block = ctx->block; 968280304Sjkim void *key = ctx->key; 969238384Sjkim#ifdef GCM_FUNCREF_4BIT 970280304Sjkim void (*gcm_gmult_p) (u64 Xi[2], const u128 Htable[16]) = ctx->gmult; 971238384Sjkim# ifdef GHASH 972280304Sjkim void (*gcm_ghash_p) (u64 Xi[2], const u128 Htable[16], 973280304Sjkim const u8 *inp, size_t len) = ctx->ghash; 974238384Sjkim# endif 975238384Sjkim#endif 976238384Sjkim 977238384Sjkim#if 0 978280304Sjkim n = (unsigned int)mlen % 16; /* alternative to ctx->mres */ 979238384Sjkim#endif 980280304Sjkim mlen += len; 981280304Sjkim if (mlen > ((U64(1) << 36) - 32) || (sizeof(len) == 8 && mlen < len)) 982280304Sjkim return -1; 983280304Sjkim ctx->len.u[1] = mlen; 984238384Sjkim 985280304Sjkim if (ctx->ares) { 986280304Sjkim /* First call to encrypt finalizes GHASH(AAD) */ 987280304Sjkim GCM_MUL(ctx, Xi); 988280304Sjkim ctx->ares = 0; 989280304Sjkim } 990238384Sjkim 991280304Sjkim if (is_endian.little) 992264331Sjkim#ifdef BSWAP4 993280304Sjkim ctr = BSWAP4(ctx->Yi.d[3]); 994264331Sjkim#else 995280304Sjkim ctr = GETU32(ctx->Yi.c + 12); 996264331Sjkim#endif 997280304Sjkim else 998280304Sjkim ctr = ctx->Yi.d[3]; 999238384Sjkim 1000280304Sjkim n = ctx->mres; 1001238384Sjkim#if !defined(OPENSSL_SMALL_FOOTPRINT) 1002280304Sjkim if (16 % sizeof(size_t) == 0) { /* always true actually */ 1003280304Sjkim do { 1004280304Sjkim if (n) { 1005280304Sjkim while (n && len) { 1006280304Sjkim ctx->Xi.c[n] ^= *(out++) = *(in++) ^ ctx->EKi.c[n]; 1007280304Sjkim --len; 1008280304Sjkim n = (n + 1) % 16; 1009280304Sjkim } 1010280304Sjkim if (n == 0) 1011280304Sjkim GCM_MUL(ctx, Xi); 1012280304Sjkim else { 1013280304Sjkim ctx->mres = n; 1014280304Sjkim return 0; 1015280304Sjkim } 1016280304Sjkim } 1017280304Sjkim# if defined(STRICT_ALIGNMENT) 1018280304Sjkim if (((size_t)in | (size_t)out) % sizeof(size_t) != 0) 1019280304Sjkim break; 1020280304Sjkim# endif 1021280304Sjkim# if defined(GHASH) && defined(GHASH_CHUNK) 1022280304Sjkim while (len >= GHASH_CHUNK) { 1023280304Sjkim size_t j = GHASH_CHUNK; 1024238384Sjkim 1025280304Sjkim while (j) { 1026280304Sjkim size_t *out_t = (size_t *)out; 1027280304Sjkim const size_t *in_t = (const size_t *)in; 1028264331Sjkim 1029280304Sjkim (*block) (ctx->Yi.c, ctx->EKi.c, key); 1030280304Sjkim ++ctr; 1031280304Sjkim if (is_endian.little) 1032280304Sjkim# ifdef BSWAP4 1033280304Sjkim ctx->Yi.d[3] = BSWAP4(ctr); 1034280304Sjkim# else 1035280304Sjkim PUTU32(ctx->Yi.c + 12, ctr); 1036280304Sjkim# endif 1037280304Sjkim else 1038280304Sjkim ctx->Yi.d[3] = ctr; 1039280304Sjkim for (i = 0; i < 16 / sizeof(size_t); ++i) 1040280304Sjkim out_t[i] = in_t[i] ^ ctx->EKi.t[i]; 1041280304Sjkim out += 16; 1042280304Sjkim in += 16; 1043280304Sjkim j -= 16; 1044280304Sjkim } 1045280304Sjkim GHASH(ctx, out - GHASH_CHUNK, GHASH_CHUNK); 1046280304Sjkim len -= GHASH_CHUNK; 1047280304Sjkim } 1048280304Sjkim if ((i = (len & (size_t)-16))) { 1049280304Sjkim size_t j = i; 1050238384Sjkim 1051280304Sjkim while (len >= 16) { 1052280304Sjkim size_t *out_t = (size_t *)out; 1053280304Sjkim const size_t *in_t = (const size_t *)in; 1054264331Sjkim 1055280304Sjkim (*block) (ctx->Yi.c, ctx->EKi.c, key); 1056280304Sjkim ++ctr; 1057280304Sjkim if (is_endian.little) 1058280304Sjkim# ifdef BSWAP4 1059280304Sjkim ctx->Yi.d[3] = BSWAP4(ctr); 1060280304Sjkim# else 1061280304Sjkim PUTU32(ctx->Yi.c + 12, ctr); 1062280304Sjkim# endif 1063280304Sjkim else 1064280304Sjkim ctx->Yi.d[3] = ctr; 1065280304Sjkim for (i = 0; i < 16 / sizeof(size_t); ++i) 1066280304Sjkim out_t[i] = in_t[i] ^ ctx->EKi.t[i]; 1067280304Sjkim out += 16; 1068280304Sjkim in += 16; 1069280304Sjkim len -= 16; 1070280304Sjkim } 1071280304Sjkim GHASH(ctx, out - j, j); 1072280304Sjkim } 1073280304Sjkim# else 1074280304Sjkim while (len >= 16) { 1075280304Sjkim size_t *out_t = (size_t *)out; 1076280304Sjkim const size_t *in_t = (const size_t *)in; 1077264331Sjkim 1078280304Sjkim (*block) (ctx->Yi.c, ctx->EKi.c, key); 1079280304Sjkim ++ctr; 1080280304Sjkim if (is_endian.little) 1081280304Sjkim# ifdef BSWAP4 1082280304Sjkim ctx->Yi.d[3] = BSWAP4(ctr); 1083280304Sjkim# else 1084280304Sjkim PUTU32(ctx->Yi.c + 12, ctr); 1085280304Sjkim# endif 1086280304Sjkim else 1087280304Sjkim ctx->Yi.d[3] = ctr; 1088280304Sjkim for (i = 0; i < 16 / sizeof(size_t); ++i) 1089280304Sjkim ctx->Xi.t[i] ^= out_t[i] = in_t[i] ^ ctx->EKi.t[i]; 1090280304Sjkim GCM_MUL(ctx, Xi); 1091280304Sjkim out += 16; 1092280304Sjkim in += 16; 1093280304Sjkim len -= 16; 1094280304Sjkim } 1095280304Sjkim# endif 1096280304Sjkim if (len) { 1097280304Sjkim (*block) (ctx->Yi.c, ctx->EKi.c, key); 1098280304Sjkim ++ctr; 1099280304Sjkim if (is_endian.little) 1100280304Sjkim# ifdef BSWAP4 1101280304Sjkim ctx->Yi.d[3] = BSWAP4(ctr); 1102280304Sjkim# else 1103280304Sjkim PUTU32(ctx->Yi.c + 12, ctr); 1104280304Sjkim# endif 1105280304Sjkim else 1106280304Sjkim ctx->Yi.d[3] = ctr; 1107280304Sjkim while (len--) { 1108280304Sjkim ctx->Xi.c[n] ^= out[n] = in[n] ^ ctx->EKi.c[n]; 1109280304Sjkim ++n; 1110280304Sjkim } 1111280304Sjkim } 1112238384Sjkim 1113280304Sjkim ctx->mres = n; 1114280304Sjkim return 0; 1115280304Sjkim } while (0); 1116280304Sjkim } 1117238384Sjkim#endif 1118280304Sjkim for (i = 0; i < len; ++i) { 1119280304Sjkim if (n == 0) { 1120280304Sjkim (*block) (ctx->Yi.c, ctx->EKi.c, key); 1121280304Sjkim ++ctr; 1122280304Sjkim if (is_endian.little) 1123264331Sjkim#ifdef BSWAP4 1124280304Sjkim ctx->Yi.d[3] = BSWAP4(ctr); 1125264331Sjkim#else 1126280304Sjkim PUTU32(ctx->Yi.c + 12, ctr); 1127264331Sjkim#endif 1128280304Sjkim else 1129280304Sjkim ctx->Yi.d[3] = ctr; 1130280304Sjkim } 1131280304Sjkim ctx->Xi.c[n] ^= out[i] = in[i] ^ ctx->EKi.c[n]; 1132280304Sjkim n = (n + 1) % 16; 1133280304Sjkim if (n == 0) 1134280304Sjkim GCM_MUL(ctx, Xi); 1135280304Sjkim } 1136238384Sjkim 1137280304Sjkim ctx->mres = n; 1138280304Sjkim return 0; 1139238384Sjkim} 1140238384Sjkim 1141238384Sjkimint CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx, 1142280304Sjkim const unsigned char *in, unsigned char *out, 1143280304Sjkim size_t len) 1144238384Sjkim{ 1145280304Sjkim const union { 1146280304Sjkim long one; 1147280304Sjkim char little; 1148280304Sjkim } is_endian = { 1149280304Sjkim 1 1150280304Sjkim }; 1151280304Sjkim unsigned int n, ctr; 1152280304Sjkim size_t i; 1153280304Sjkim u64 mlen = ctx->len.u[1]; 1154280304Sjkim block128_f block = ctx->block; 1155280304Sjkim void *key = ctx->key; 1156238384Sjkim#ifdef GCM_FUNCREF_4BIT 1157280304Sjkim void (*gcm_gmult_p) (u64 Xi[2], const u128 Htable[16]) = ctx->gmult; 1158238384Sjkim# ifdef GHASH 1159280304Sjkim void (*gcm_ghash_p) (u64 Xi[2], const u128 Htable[16], 1160280304Sjkim const u8 *inp, size_t len) = ctx->ghash; 1161238384Sjkim# endif 1162238384Sjkim#endif 1163238384Sjkim 1164280304Sjkim mlen += len; 1165280304Sjkim if (mlen > ((U64(1) << 36) - 32) || (sizeof(len) == 8 && mlen < len)) 1166280304Sjkim return -1; 1167280304Sjkim ctx->len.u[1] = mlen; 1168238384Sjkim 1169280304Sjkim if (ctx->ares) { 1170280304Sjkim /* First call to decrypt finalizes GHASH(AAD) */ 1171280304Sjkim GCM_MUL(ctx, Xi); 1172280304Sjkim ctx->ares = 0; 1173280304Sjkim } 1174238384Sjkim 1175280304Sjkim if (is_endian.little) 1176264331Sjkim#ifdef BSWAP4 1177280304Sjkim ctr = BSWAP4(ctx->Yi.d[3]); 1178264331Sjkim#else 1179280304Sjkim ctr = GETU32(ctx->Yi.c + 12); 1180264331Sjkim#endif 1181280304Sjkim else 1182280304Sjkim ctr = ctx->Yi.d[3]; 1183238384Sjkim 1184280304Sjkim n = ctx->mres; 1185238384Sjkim#if !defined(OPENSSL_SMALL_FOOTPRINT) 1186280304Sjkim if (16 % sizeof(size_t) == 0) { /* always true actually */ 1187280304Sjkim do { 1188280304Sjkim if (n) { 1189280304Sjkim while (n && len) { 1190280304Sjkim u8 c = *(in++); 1191280304Sjkim *(out++) = c ^ ctx->EKi.c[n]; 1192280304Sjkim ctx->Xi.c[n] ^= c; 1193280304Sjkim --len; 1194280304Sjkim n = (n + 1) % 16; 1195280304Sjkim } 1196280304Sjkim if (n == 0) 1197280304Sjkim GCM_MUL(ctx, Xi); 1198280304Sjkim else { 1199280304Sjkim ctx->mres = n; 1200280304Sjkim return 0; 1201280304Sjkim } 1202280304Sjkim } 1203280304Sjkim# if defined(STRICT_ALIGNMENT) 1204280304Sjkim if (((size_t)in | (size_t)out) % sizeof(size_t) != 0) 1205280304Sjkim break; 1206280304Sjkim# endif 1207280304Sjkim# if defined(GHASH) && defined(GHASH_CHUNK) 1208280304Sjkim while (len >= GHASH_CHUNK) { 1209280304Sjkim size_t j = GHASH_CHUNK; 1210238384Sjkim 1211280304Sjkim GHASH(ctx, in, GHASH_CHUNK); 1212280304Sjkim while (j) { 1213280304Sjkim size_t *out_t = (size_t *)out; 1214280304Sjkim const size_t *in_t = (const size_t *)in; 1215264331Sjkim 1216280304Sjkim (*block) (ctx->Yi.c, ctx->EKi.c, key); 1217280304Sjkim ++ctr; 1218280304Sjkim if (is_endian.little) 1219280304Sjkim# ifdef BSWAP4 1220280304Sjkim ctx->Yi.d[3] = BSWAP4(ctr); 1221280304Sjkim# else 1222280304Sjkim PUTU32(ctx->Yi.c + 12, ctr); 1223280304Sjkim# endif 1224280304Sjkim else 1225280304Sjkim ctx->Yi.d[3] = ctr; 1226280304Sjkim for (i = 0; i < 16 / sizeof(size_t); ++i) 1227280304Sjkim out_t[i] = in_t[i] ^ ctx->EKi.t[i]; 1228280304Sjkim out += 16; 1229280304Sjkim in += 16; 1230280304Sjkim j -= 16; 1231280304Sjkim } 1232280304Sjkim len -= GHASH_CHUNK; 1233280304Sjkim } 1234280304Sjkim if ((i = (len & (size_t)-16))) { 1235280304Sjkim GHASH(ctx, in, i); 1236280304Sjkim while (len >= 16) { 1237280304Sjkim size_t *out_t = (size_t *)out; 1238280304Sjkim const size_t *in_t = (const size_t *)in; 1239264331Sjkim 1240280304Sjkim (*block) (ctx->Yi.c, ctx->EKi.c, key); 1241280304Sjkim ++ctr; 1242280304Sjkim if (is_endian.little) 1243280304Sjkim# ifdef BSWAP4 1244280304Sjkim ctx->Yi.d[3] = BSWAP4(ctr); 1245280304Sjkim# else 1246280304Sjkim PUTU32(ctx->Yi.c + 12, ctr); 1247280304Sjkim# endif 1248280304Sjkim else 1249280304Sjkim ctx->Yi.d[3] = ctr; 1250280304Sjkim for (i = 0; i < 16 / sizeof(size_t); ++i) 1251280304Sjkim out_t[i] = in_t[i] ^ ctx->EKi.t[i]; 1252280304Sjkim out += 16; 1253280304Sjkim in += 16; 1254280304Sjkim len -= 16; 1255280304Sjkim } 1256280304Sjkim } 1257280304Sjkim# else 1258280304Sjkim while (len >= 16) { 1259280304Sjkim size_t *out_t = (size_t *)out; 1260280304Sjkim const size_t *in_t = (const size_t *)in; 1261264331Sjkim 1262280304Sjkim (*block) (ctx->Yi.c, ctx->EKi.c, key); 1263280304Sjkim ++ctr; 1264280304Sjkim if (is_endian.little) 1265280304Sjkim# ifdef BSWAP4 1266280304Sjkim ctx->Yi.d[3] = BSWAP4(ctr); 1267280304Sjkim# else 1268280304Sjkim PUTU32(ctx->Yi.c + 12, ctr); 1269280304Sjkim# endif 1270280304Sjkim else 1271280304Sjkim ctx->Yi.d[3] = ctr; 1272280304Sjkim for (i = 0; i < 16 / sizeof(size_t); ++i) { 1273280304Sjkim size_t c = in[i]; 1274280304Sjkim out[i] = c ^ ctx->EKi.t[i]; 1275280304Sjkim ctx->Xi.t[i] ^= c; 1276280304Sjkim } 1277280304Sjkim GCM_MUL(ctx, Xi); 1278280304Sjkim out += 16; 1279280304Sjkim in += 16; 1280280304Sjkim len -= 16; 1281280304Sjkim } 1282280304Sjkim# endif 1283280304Sjkim if (len) { 1284280304Sjkim (*block) (ctx->Yi.c, ctx->EKi.c, key); 1285280304Sjkim ++ctr; 1286280304Sjkim if (is_endian.little) 1287280304Sjkim# ifdef BSWAP4 1288280304Sjkim ctx->Yi.d[3] = BSWAP4(ctr); 1289280304Sjkim# else 1290280304Sjkim PUTU32(ctx->Yi.c + 12, ctr); 1291280304Sjkim# endif 1292280304Sjkim else 1293280304Sjkim ctx->Yi.d[3] = ctr; 1294280304Sjkim while (len--) { 1295280304Sjkim u8 c = in[n]; 1296280304Sjkim ctx->Xi.c[n] ^= c; 1297280304Sjkim out[n] = c ^ ctx->EKi.c[n]; 1298280304Sjkim ++n; 1299280304Sjkim } 1300280304Sjkim } 1301238384Sjkim 1302280304Sjkim ctx->mres = n; 1303280304Sjkim return 0; 1304280304Sjkim } while (0); 1305280304Sjkim } 1306238384Sjkim#endif 1307280304Sjkim for (i = 0; i < len; ++i) { 1308280304Sjkim u8 c; 1309280304Sjkim if (n == 0) { 1310280304Sjkim (*block) (ctx->Yi.c, ctx->EKi.c, key); 1311280304Sjkim ++ctr; 1312280304Sjkim if (is_endian.little) 1313264331Sjkim#ifdef BSWAP4 1314280304Sjkim ctx->Yi.d[3] = BSWAP4(ctr); 1315264331Sjkim#else 1316280304Sjkim PUTU32(ctx->Yi.c + 12, ctr); 1317264331Sjkim#endif 1318280304Sjkim else 1319280304Sjkim ctx->Yi.d[3] = ctr; 1320280304Sjkim } 1321280304Sjkim c = in[i]; 1322280304Sjkim out[i] = c ^ ctx->EKi.c[n]; 1323280304Sjkim ctx->Xi.c[n] ^= c; 1324280304Sjkim n = (n + 1) % 16; 1325280304Sjkim if (n == 0) 1326280304Sjkim GCM_MUL(ctx, Xi); 1327280304Sjkim } 1328238384Sjkim 1329280304Sjkim ctx->mres = n; 1330280304Sjkim return 0; 1331238384Sjkim} 1332238384Sjkim 1333238384Sjkimint CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx, 1334280304Sjkim const unsigned char *in, unsigned char *out, 1335280304Sjkim size_t len, ctr128_f stream) 1336238384Sjkim{ 1337280304Sjkim const union { 1338280304Sjkim long one; 1339280304Sjkim char little; 1340280304Sjkim } is_endian = { 1341280304Sjkim 1 1342280304Sjkim }; 1343280304Sjkim unsigned int n, ctr; 1344280304Sjkim size_t i; 1345280304Sjkim u64 mlen = ctx->len.u[1]; 1346280304Sjkim void *key = ctx->key; 1347238384Sjkim#ifdef GCM_FUNCREF_4BIT 1348280304Sjkim void (*gcm_gmult_p) (u64 Xi[2], const u128 Htable[16]) = ctx->gmult; 1349238384Sjkim# ifdef GHASH 1350280304Sjkim void (*gcm_ghash_p) (u64 Xi[2], const u128 Htable[16], 1351280304Sjkim const u8 *inp, size_t len) = ctx->ghash; 1352238384Sjkim# endif 1353238384Sjkim#endif 1354238384Sjkim 1355280304Sjkim mlen += len; 1356280304Sjkim if (mlen > ((U64(1) << 36) - 32) || (sizeof(len) == 8 && mlen < len)) 1357280304Sjkim return -1; 1358280304Sjkim ctx->len.u[1] = mlen; 1359238384Sjkim 1360280304Sjkim if (ctx->ares) { 1361280304Sjkim /* First call to encrypt finalizes GHASH(AAD) */ 1362280304Sjkim GCM_MUL(ctx, Xi); 1363280304Sjkim ctx->ares = 0; 1364280304Sjkim } 1365238384Sjkim 1366280304Sjkim if (is_endian.little) 1367264331Sjkim#ifdef BSWAP4 1368280304Sjkim ctr = BSWAP4(ctx->Yi.d[3]); 1369264331Sjkim#else 1370280304Sjkim ctr = GETU32(ctx->Yi.c + 12); 1371264331Sjkim#endif 1372280304Sjkim else 1373280304Sjkim ctr = ctx->Yi.d[3]; 1374238384Sjkim 1375280304Sjkim n = ctx->mres; 1376280304Sjkim if (n) { 1377280304Sjkim while (n && len) { 1378280304Sjkim ctx->Xi.c[n] ^= *(out++) = *(in++) ^ ctx->EKi.c[n]; 1379280304Sjkim --len; 1380280304Sjkim n = (n + 1) % 16; 1381280304Sjkim } 1382280304Sjkim if (n == 0) 1383280304Sjkim GCM_MUL(ctx, Xi); 1384280304Sjkim else { 1385280304Sjkim ctx->mres = n; 1386280304Sjkim return 0; 1387280304Sjkim } 1388280304Sjkim } 1389238384Sjkim#if defined(GHASH) && !defined(OPENSSL_SMALL_FOOTPRINT) 1390280304Sjkim while (len >= GHASH_CHUNK) { 1391280304Sjkim (*stream) (in, out, GHASH_CHUNK / 16, key, ctx->Yi.c); 1392280304Sjkim ctr += GHASH_CHUNK / 16; 1393280304Sjkim if (is_endian.little) 1394280304Sjkim# ifdef BSWAP4 1395280304Sjkim ctx->Yi.d[3] = BSWAP4(ctr); 1396280304Sjkim# else 1397280304Sjkim PUTU32(ctx->Yi.c + 12, ctr); 1398280304Sjkim# endif 1399280304Sjkim else 1400280304Sjkim ctx->Yi.d[3] = ctr; 1401280304Sjkim GHASH(ctx, out, GHASH_CHUNK); 1402280304Sjkim out += GHASH_CHUNK; 1403280304Sjkim in += GHASH_CHUNK; 1404280304Sjkim len -= GHASH_CHUNK; 1405280304Sjkim } 1406264331Sjkim#endif 1407280304Sjkim if ((i = (len & (size_t)-16))) { 1408280304Sjkim size_t j = i / 16; 1409238384Sjkim 1410280304Sjkim (*stream) (in, out, j, key, ctx->Yi.c); 1411280304Sjkim ctr += (unsigned int)j; 1412280304Sjkim if (is_endian.little) 1413264331Sjkim#ifdef BSWAP4 1414280304Sjkim ctx->Yi.d[3] = BSWAP4(ctr); 1415264331Sjkim#else 1416280304Sjkim PUTU32(ctx->Yi.c + 12, ctr); 1417264331Sjkim#endif 1418280304Sjkim else 1419280304Sjkim ctx->Yi.d[3] = ctr; 1420280304Sjkim in += i; 1421280304Sjkim len -= i; 1422238384Sjkim#if defined(GHASH) 1423280304Sjkim GHASH(ctx, out, i); 1424280304Sjkim out += i; 1425238384Sjkim#else 1426280304Sjkim while (j--) { 1427280304Sjkim for (i = 0; i < 16; ++i) 1428280304Sjkim ctx->Xi.c[i] ^= out[i]; 1429280304Sjkim GCM_MUL(ctx, Xi); 1430280304Sjkim out += 16; 1431280304Sjkim } 1432238384Sjkim#endif 1433280304Sjkim } 1434280304Sjkim if (len) { 1435280304Sjkim (*ctx->block) (ctx->Yi.c, ctx->EKi.c, key); 1436280304Sjkim ++ctr; 1437280304Sjkim if (is_endian.little) 1438264331Sjkim#ifdef BSWAP4 1439280304Sjkim ctx->Yi.d[3] = BSWAP4(ctr); 1440264331Sjkim#else 1441280304Sjkim PUTU32(ctx->Yi.c + 12, ctr); 1442264331Sjkim#endif 1443280304Sjkim else 1444280304Sjkim ctx->Yi.d[3] = ctr; 1445280304Sjkim while (len--) { 1446280304Sjkim ctx->Xi.c[n] ^= out[n] = in[n] ^ ctx->EKi.c[n]; 1447280304Sjkim ++n; 1448280304Sjkim } 1449280304Sjkim } 1450238384Sjkim 1451280304Sjkim ctx->mres = n; 1452280304Sjkim return 0; 1453238384Sjkim} 1454238384Sjkim 1455238384Sjkimint CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx, 1456280304Sjkim const unsigned char *in, unsigned char *out, 1457280304Sjkim size_t len, ctr128_f stream) 1458238384Sjkim{ 1459280304Sjkim const union { 1460280304Sjkim long one; 1461280304Sjkim char little; 1462280304Sjkim } is_endian = { 1463280304Sjkim 1 1464280304Sjkim }; 1465280304Sjkim unsigned int n, ctr; 1466280304Sjkim size_t i; 1467280304Sjkim u64 mlen = ctx->len.u[1]; 1468280304Sjkim void *key = ctx->key; 1469238384Sjkim#ifdef GCM_FUNCREF_4BIT 1470280304Sjkim void (*gcm_gmult_p) (u64 Xi[2], const u128 Htable[16]) = ctx->gmult; 1471238384Sjkim# ifdef GHASH 1472280304Sjkim void (*gcm_ghash_p) (u64 Xi[2], const u128 Htable[16], 1473280304Sjkim const u8 *inp, size_t len) = ctx->ghash; 1474238384Sjkim# endif 1475238384Sjkim#endif 1476238384Sjkim 1477280304Sjkim mlen += len; 1478280304Sjkim if (mlen > ((U64(1) << 36) - 32) || (sizeof(len) == 8 && mlen < len)) 1479280304Sjkim return -1; 1480280304Sjkim ctx->len.u[1] = mlen; 1481238384Sjkim 1482280304Sjkim if (ctx->ares) { 1483280304Sjkim /* First call to decrypt finalizes GHASH(AAD) */ 1484280304Sjkim GCM_MUL(ctx, Xi); 1485280304Sjkim ctx->ares = 0; 1486280304Sjkim } 1487238384Sjkim 1488280304Sjkim if (is_endian.little) 1489264331Sjkim#ifdef BSWAP4 1490280304Sjkim ctr = BSWAP4(ctx->Yi.d[3]); 1491264331Sjkim#else 1492280304Sjkim ctr = GETU32(ctx->Yi.c + 12); 1493264331Sjkim#endif 1494280304Sjkim else 1495280304Sjkim ctr = ctx->Yi.d[3]; 1496238384Sjkim 1497280304Sjkim n = ctx->mres; 1498280304Sjkim if (n) { 1499280304Sjkim while (n && len) { 1500280304Sjkim u8 c = *(in++); 1501280304Sjkim *(out++) = c ^ ctx->EKi.c[n]; 1502280304Sjkim ctx->Xi.c[n] ^= c; 1503280304Sjkim --len; 1504280304Sjkim n = (n + 1) % 16; 1505280304Sjkim } 1506280304Sjkim if (n == 0) 1507280304Sjkim GCM_MUL(ctx, Xi); 1508280304Sjkim else { 1509280304Sjkim ctx->mres = n; 1510280304Sjkim return 0; 1511280304Sjkim } 1512280304Sjkim } 1513238384Sjkim#if defined(GHASH) && !defined(OPENSSL_SMALL_FOOTPRINT) 1514280304Sjkim while (len >= GHASH_CHUNK) { 1515280304Sjkim GHASH(ctx, in, GHASH_CHUNK); 1516280304Sjkim (*stream) (in, out, GHASH_CHUNK / 16, key, ctx->Yi.c); 1517280304Sjkim ctr += GHASH_CHUNK / 16; 1518280304Sjkim if (is_endian.little) 1519280304Sjkim# ifdef BSWAP4 1520280304Sjkim ctx->Yi.d[3] = BSWAP4(ctr); 1521280304Sjkim# else 1522280304Sjkim PUTU32(ctx->Yi.c + 12, ctr); 1523280304Sjkim# endif 1524280304Sjkim else 1525280304Sjkim ctx->Yi.d[3] = ctr; 1526280304Sjkim out += GHASH_CHUNK; 1527280304Sjkim in += GHASH_CHUNK; 1528280304Sjkim len -= GHASH_CHUNK; 1529280304Sjkim } 1530264331Sjkim#endif 1531280304Sjkim if ((i = (len & (size_t)-16))) { 1532280304Sjkim size_t j = i / 16; 1533238384Sjkim 1534238384Sjkim#if defined(GHASH) 1535280304Sjkim GHASH(ctx, in, i); 1536238384Sjkim#else 1537280304Sjkim while (j--) { 1538280304Sjkim size_t k; 1539280304Sjkim for (k = 0; k < 16; ++k) 1540280304Sjkim ctx->Xi.c[k] ^= in[k]; 1541280304Sjkim GCM_MUL(ctx, Xi); 1542280304Sjkim in += 16; 1543280304Sjkim } 1544280304Sjkim j = i / 16; 1545280304Sjkim in -= i; 1546238384Sjkim#endif 1547280304Sjkim (*stream) (in, out, j, key, ctx->Yi.c); 1548280304Sjkim ctr += (unsigned int)j; 1549280304Sjkim if (is_endian.little) 1550264331Sjkim#ifdef BSWAP4 1551280304Sjkim ctx->Yi.d[3] = BSWAP4(ctr); 1552264331Sjkim#else 1553280304Sjkim PUTU32(ctx->Yi.c + 12, ctr); 1554264331Sjkim#endif 1555280304Sjkim else 1556280304Sjkim ctx->Yi.d[3] = ctr; 1557280304Sjkim out += i; 1558280304Sjkim in += i; 1559280304Sjkim len -= i; 1560280304Sjkim } 1561280304Sjkim if (len) { 1562280304Sjkim (*ctx->block) (ctx->Yi.c, ctx->EKi.c, key); 1563280304Sjkim ++ctr; 1564280304Sjkim if (is_endian.little) 1565264331Sjkim#ifdef BSWAP4 1566280304Sjkim ctx->Yi.d[3] = BSWAP4(ctr); 1567264331Sjkim#else 1568280304Sjkim PUTU32(ctx->Yi.c + 12, ctr); 1569264331Sjkim#endif 1570280304Sjkim else 1571280304Sjkim ctx->Yi.d[3] = ctr; 1572280304Sjkim while (len--) { 1573280304Sjkim u8 c = in[n]; 1574280304Sjkim ctx->Xi.c[n] ^= c; 1575280304Sjkim out[n] = c ^ ctx->EKi.c[n]; 1576280304Sjkim ++n; 1577280304Sjkim } 1578280304Sjkim } 1579238384Sjkim 1580280304Sjkim ctx->mres = n; 1581280304Sjkim return 0; 1582238384Sjkim} 1583238384Sjkim 1584280304Sjkimint CRYPTO_gcm128_finish(GCM128_CONTEXT *ctx, const unsigned char *tag, 1585280304Sjkim size_t len) 1586238384Sjkim{ 1587280304Sjkim const union { 1588280304Sjkim long one; 1589280304Sjkim char little; 1590280304Sjkim } is_endian = { 1591280304Sjkim 1 1592280304Sjkim }; 1593280304Sjkim u64 alen = ctx->len.u[0] << 3; 1594280304Sjkim u64 clen = ctx->len.u[1] << 3; 1595238384Sjkim#ifdef GCM_FUNCREF_4BIT 1596280304Sjkim void (*gcm_gmult_p) (u64 Xi[2], const u128 Htable[16]) = ctx->gmult; 1597238384Sjkim#endif 1598238384Sjkim 1599280304Sjkim if (ctx->mres || ctx->ares) 1600280304Sjkim GCM_MUL(ctx, Xi); 1601238384Sjkim 1602280304Sjkim if (is_endian.little) { 1603238384Sjkim#ifdef BSWAP8 1604280304Sjkim alen = BSWAP8(alen); 1605280304Sjkim clen = BSWAP8(clen); 1606238384Sjkim#else 1607280304Sjkim u8 *p = ctx->len.c; 1608238384Sjkim 1609280304Sjkim ctx->len.u[0] = alen; 1610280304Sjkim ctx->len.u[1] = clen; 1611238384Sjkim 1612280304Sjkim alen = (u64)GETU32(p) << 32 | GETU32(p + 4); 1613280304Sjkim clen = (u64)GETU32(p + 8) << 32 | GETU32(p + 12); 1614238384Sjkim#endif 1615280304Sjkim } 1616238384Sjkim 1617280304Sjkim ctx->Xi.u[0] ^= alen; 1618280304Sjkim ctx->Xi.u[1] ^= clen; 1619280304Sjkim GCM_MUL(ctx, Xi); 1620238384Sjkim 1621280304Sjkim ctx->Xi.u[0] ^= ctx->EK0.u[0]; 1622280304Sjkim ctx->Xi.u[1] ^= ctx->EK0.u[1]; 1623238384Sjkim 1624280304Sjkim if (tag && len <= sizeof(ctx->Xi)) 1625284285Sjkim return CRYPTO_memcmp(ctx->Xi.c, tag, len); 1626280304Sjkim else 1627280304Sjkim return -1; 1628238384Sjkim} 1629238384Sjkim 1630238384Sjkimvoid CRYPTO_gcm128_tag(GCM128_CONTEXT *ctx, unsigned char *tag, size_t len) 1631238384Sjkim{ 1632280304Sjkim CRYPTO_gcm128_finish(ctx, NULL, 0); 1633280304Sjkim memcpy(tag, ctx->Xi.c, 1634280304Sjkim len <= sizeof(ctx->Xi.c) ? len : sizeof(ctx->Xi.c)); 1635238384Sjkim} 1636238384Sjkim 1637238384SjkimGCM128_CONTEXT *CRYPTO_gcm128_new(void *key, block128_f block) 1638238384Sjkim{ 1639280304Sjkim GCM128_CONTEXT *ret; 1640238384Sjkim 1641280304Sjkim if ((ret = (GCM128_CONTEXT *)OPENSSL_malloc(sizeof(GCM128_CONTEXT)))) 1642280304Sjkim CRYPTO_gcm128_init(ret, key, block); 1643238384Sjkim 1644280304Sjkim return ret; 1645238384Sjkim} 1646238384Sjkim 1647238384Sjkimvoid CRYPTO_gcm128_release(GCM128_CONTEXT *ctx) 1648238384Sjkim{ 1649280304Sjkim if (ctx) { 1650280304Sjkim OPENSSL_cleanse(ctx, sizeof(*ctx)); 1651280304Sjkim OPENSSL_free(ctx); 1652280304Sjkim } 1653238384Sjkim} 1654238384Sjkim 1655238384Sjkim#if defined(SELFTEST) 1656280304Sjkim# include <stdio.h> 1657280304Sjkim# include <openssl/aes.h> 1658238384Sjkim 1659238384Sjkim/* Test Case 1 */ 1660280304Sjkimstatic const u8 K1[16], *P1 = NULL, *A1 = NULL, IV1[12], *C1 = NULL; 1661280304Sjkimstatic const u8 T1[] = { 1662280304Sjkim 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61, 1663280304Sjkim 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a 1664280304Sjkim}; 1665238384Sjkim 1666238384Sjkim/* Test Case 2 */ 1667280304Sjkim# define K2 K1 1668280304Sjkim# define A2 A1 1669280304Sjkim# define IV2 IV1 1670280304Sjkimstatic const u8 P2[16]; 1671280304Sjkimstatic const u8 C2[] = { 1672280304Sjkim 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92, 1673280304Sjkim 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 1674280304Sjkim}; 1675238384Sjkim 1676280304Sjkimstatic const u8 T2[] = { 1677280304Sjkim 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd, 1678280304Sjkim 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf 1679280304Sjkim}; 1680280304Sjkim 1681238384Sjkim/* Test Case 3 */ 1682280304Sjkim# define A3 A2 1683280304Sjkimstatic const u8 K3[] = { 1684280304Sjkim 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, 1685280304Sjkim 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 1686280304Sjkim}; 1687238384Sjkim 1688280304Sjkimstatic const u8 P3[] = { 1689280304Sjkim 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, 1690280304Sjkim 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, 1691280304Sjkim 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, 1692280304Sjkim 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, 1693280304Sjkim 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, 1694280304Sjkim 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, 1695280304Sjkim 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, 1696280304Sjkim 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 1697280304Sjkim}; 1698280304Sjkim 1699280304Sjkimstatic const u8 IV3[] = { 1700280304Sjkim 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, 1701280304Sjkim 0xde, 0xca, 0xf8, 0x88 1702280304Sjkim}; 1703280304Sjkim 1704280304Sjkimstatic const u8 C3[] = { 1705280304Sjkim 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, 1706280304Sjkim 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c, 1707280304Sjkim 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, 1708280304Sjkim 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e, 1709280304Sjkim 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, 1710280304Sjkim 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, 1711280304Sjkim 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97, 1712280304Sjkim 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 1713280304Sjkim}; 1714280304Sjkim 1715280304Sjkimstatic const u8 T3[] = { 1716280304Sjkim 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6, 1717280304Sjkim 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 1718280304Sjkim}; 1719280304Sjkim 1720238384Sjkim/* Test Case 4 */ 1721280304Sjkim# define K4 K3 1722280304Sjkim# define IV4 IV3 1723280304Sjkimstatic const u8 P4[] = { 1724280304Sjkim 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, 1725280304Sjkim 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, 1726280304Sjkim 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, 1727280304Sjkim 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, 1728280304Sjkim 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, 1729280304Sjkim 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, 1730280304Sjkim 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, 1731280304Sjkim 0xba, 0x63, 0x7b, 0x39 1732280304Sjkim}; 1733238384Sjkim 1734280304Sjkimstatic const u8 A4[] = { 1735280304Sjkim 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 1736280304Sjkim 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 1737280304Sjkim 0xab, 0xad, 0xda, 0xd2 1738280304Sjkim}; 1739280304Sjkim 1740280304Sjkimstatic const u8 C4[] = { 1741280304Sjkim 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, 1742280304Sjkim 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c, 1743280304Sjkim 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, 1744280304Sjkim 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e, 1745280304Sjkim 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, 1746280304Sjkim 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, 1747280304Sjkim 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97, 1748280304Sjkim 0x3d, 0x58, 0xe0, 0x91 1749280304Sjkim}; 1750280304Sjkim 1751280304Sjkimstatic const u8 T4[] = { 1752280304Sjkim 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb, 1753280304Sjkim 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 1754280304Sjkim}; 1755280304Sjkim 1756238384Sjkim/* Test Case 5 */ 1757280304Sjkim# define K5 K4 1758280304Sjkim# define P5 P4 1759280304Sjkim# define A5 A4 1760280304Sjkimstatic const u8 IV5[] = { 1761280304Sjkim 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad 1762280304Sjkim}; 1763238384Sjkim 1764280304Sjkimstatic const u8 C5[] = { 1765280304Sjkim 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a, 1766280304Sjkim 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55, 1767280304Sjkim 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8, 1768280304Sjkim 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23, 1769280304Sjkim 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2, 1770280304Sjkim 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42, 1771280304Sjkim 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07, 1772280304Sjkim 0xc2, 0x3f, 0x45, 0x98 1773280304Sjkim}; 1774280304Sjkim 1775280304Sjkimstatic const u8 T5[] = { 1776280304Sjkim 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85, 1777280304Sjkim 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb 1778280304Sjkim}; 1779280304Sjkim 1780238384Sjkim/* Test Case 6 */ 1781280304Sjkim# define K6 K5 1782280304Sjkim# define P6 P5 1783280304Sjkim# define A6 A5 1784280304Sjkimstatic const u8 IV6[] = { 1785280304Sjkim 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5, 1786280304Sjkim 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa, 1787280304Sjkim 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1, 1788280304Sjkim 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28, 1789280304Sjkim 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39, 1790280304Sjkim 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54, 1791280304Sjkim 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57, 1792280304Sjkim 0xa6, 0x37, 0xb3, 0x9b 1793280304Sjkim}; 1794238384Sjkim 1795280304Sjkimstatic const u8 C6[] = { 1796280304Sjkim 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6, 1797280304Sjkim 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94, 1798280304Sjkim 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8, 1799280304Sjkim 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7, 1800280304Sjkim 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90, 1801280304Sjkim 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f, 1802280304Sjkim 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03, 1803280304Sjkim 0x4c, 0x34, 0xae, 0xe5 1804280304Sjkim}; 1805280304Sjkim 1806280304Sjkimstatic const u8 T6[] = { 1807280304Sjkim 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa, 1808280304Sjkim 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 1809280304Sjkim}; 1810280304Sjkim 1811238384Sjkim/* Test Case 7 */ 1812280304Sjkimstatic const u8 K7[24], *P7 = NULL, *A7 = NULL, IV7[12], *C7 = NULL; 1813280304Sjkimstatic const u8 T7[] = { 1814280304Sjkim 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b, 1815280304Sjkim 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 1816280304Sjkim}; 1817238384Sjkim 1818238384Sjkim/* Test Case 8 */ 1819280304Sjkim# define K8 K7 1820280304Sjkim# define IV8 IV7 1821280304Sjkim# define A8 A7 1822280304Sjkimstatic const u8 P8[16]; 1823280304Sjkimstatic const u8 C8[] = { 1824280304Sjkim 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41, 1825280304Sjkim 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 1826280304Sjkim}; 1827238384Sjkim 1828280304Sjkimstatic const u8 T8[] = { 1829280304Sjkim 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab, 1830280304Sjkim 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb 1831280304Sjkim}; 1832280304Sjkim 1833238384Sjkim/* Test Case 9 */ 1834280304Sjkim# define A9 A8 1835280304Sjkimstatic const u8 K9[] = { 1836280304Sjkim 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, 1837280304Sjkim 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, 1838280304Sjkim 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c 1839280304Sjkim}; 1840238384Sjkim 1841280304Sjkimstatic const u8 P9[] = { 1842280304Sjkim 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, 1843280304Sjkim 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, 1844280304Sjkim 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, 1845280304Sjkim 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, 1846280304Sjkim 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, 1847280304Sjkim 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, 1848280304Sjkim 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, 1849280304Sjkim 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 1850280304Sjkim}; 1851280304Sjkim 1852280304Sjkimstatic const u8 IV9[] = { 1853280304Sjkim 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, 1854280304Sjkim 0xde, 0xca, 0xf8, 0x88 1855280304Sjkim}; 1856280304Sjkim 1857280304Sjkimstatic const u8 C9[] = { 1858280304Sjkim 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41, 1859280304Sjkim 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57, 1860280304Sjkim 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84, 1861280304Sjkim 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c, 1862280304Sjkim 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25, 1863280304Sjkim 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47, 1864280304Sjkim 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9, 1865280304Sjkim 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 1866280304Sjkim}; 1867280304Sjkim 1868280304Sjkimstatic const u8 T9[] = { 1869280304Sjkim 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf, 1870280304Sjkim 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 1871280304Sjkim}; 1872280304Sjkim 1873238384Sjkim/* Test Case 10 */ 1874280304Sjkim# define K10 K9 1875280304Sjkim# define IV10 IV9 1876280304Sjkimstatic const u8 P10[] = { 1877280304Sjkim 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, 1878280304Sjkim 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, 1879280304Sjkim 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, 1880280304Sjkim 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, 1881280304Sjkim 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, 1882280304Sjkim 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, 1883280304Sjkim 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, 1884280304Sjkim 0xba, 0x63, 0x7b, 0x39 1885280304Sjkim}; 1886238384Sjkim 1887280304Sjkimstatic const u8 A10[] = { 1888280304Sjkim 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 1889280304Sjkim 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 1890280304Sjkim 0xab, 0xad, 0xda, 0xd2 1891280304Sjkim}; 1892280304Sjkim 1893280304Sjkimstatic const u8 C10[] = { 1894280304Sjkim 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41, 1895280304Sjkim 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57, 1896280304Sjkim 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84, 1897280304Sjkim 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c, 1898280304Sjkim 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25, 1899280304Sjkim 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47, 1900280304Sjkim 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9, 1901280304Sjkim 0xcc, 0xda, 0x27, 0x10 1902280304Sjkim}; 1903280304Sjkim 1904280304Sjkimstatic const u8 T10[] = { 1905280304Sjkim 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f, 1906280304Sjkim 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c 1907280304Sjkim}; 1908280304Sjkim 1909238384Sjkim/* Test Case 11 */ 1910280304Sjkim# define K11 K10 1911280304Sjkim# define P11 P10 1912280304Sjkim# define A11 A10 1913280304Sjkimstatic const u8 IV11[] = { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad }; 1914238384Sjkim 1915280304Sjkimstatic const u8 C11[] = { 1916280304Sjkim 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54, 1917280304Sjkim 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8, 1918280304Sjkim 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f, 1919280304Sjkim 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57, 1920280304Sjkim 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75, 1921280304Sjkim 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9, 1922280304Sjkim 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f, 1923280304Sjkim 0xa0, 0xf0, 0x62, 0xf7 1924280304Sjkim}; 1925280304Sjkim 1926280304Sjkimstatic const u8 T11[] = { 1927280304Sjkim 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24, 1928280304Sjkim 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 1929280304Sjkim}; 1930280304Sjkim 1931238384Sjkim/* Test Case 12 */ 1932280304Sjkim# define K12 K11 1933280304Sjkim# define P12 P11 1934280304Sjkim# define A12 A11 1935280304Sjkimstatic const u8 IV12[] = { 1936280304Sjkim 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5, 1937280304Sjkim 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa, 1938280304Sjkim 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1, 1939280304Sjkim 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28, 1940280304Sjkim 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39, 1941280304Sjkim 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54, 1942280304Sjkim 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57, 1943280304Sjkim 0xa6, 0x37, 0xb3, 0x9b 1944280304Sjkim}; 1945238384Sjkim 1946280304Sjkimstatic const u8 C12[] = { 1947280304Sjkim 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c, 1948280304Sjkim 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff, 1949280304Sjkim 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef, 1950280304Sjkim 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45, 1951280304Sjkim 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9, 1952280304Sjkim 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3, 1953280304Sjkim 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7, 1954280304Sjkim 0xe9, 0xb7, 0x37, 0x3b 1955280304Sjkim}; 1956280304Sjkim 1957280304Sjkimstatic const u8 T12[] = { 1958280304Sjkim 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb, 1959280304Sjkim 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 1960280304Sjkim}; 1961280304Sjkim 1962238384Sjkim/* Test Case 13 */ 1963280304Sjkimstatic const u8 K13[32], *P13 = NULL, *A13 = NULL, IV13[12], *C13 = NULL; 1964280304Sjkimstatic const u8 T13[] = { 1965280304Sjkim 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9, 1966280304Sjkim 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b 1967280304Sjkim}; 1968238384Sjkim 1969238384Sjkim/* Test Case 14 */ 1970280304Sjkim# define K14 K13 1971280304Sjkim# define A14 A13 1972280304Sjkimstatic const u8 P14[16], IV14[12]; 1973280304Sjkimstatic const u8 C14[] = { 1974280304Sjkim 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e, 1975280304Sjkim 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 1976280304Sjkim}; 1977238384Sjkim 1978280304Sjkimstatic const u8 T14[] = { 1979280304Sjkim 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0, 1980280304Sjkim 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 1981280304Sjkim}; 1982280304Sjkim 1983238384Sjkim/* Test Case 15 */ 1984280304Sjkim# define A15 A14 1985280304Sjkimstatic const u8 K15[] = { 1986280304Sjkim 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, 1987280304Sjkim 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, 1988280304Sjkim 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, 1989280304Sjkim 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 1990280304Sjkim}; 1991238384Sjkim 1992280304Sjkimstatic const u8 P15[] = { 1993280304Sjkim 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, 1994280304Sjkim 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, 1995280304Sjkim 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, 1996280304Sjkim 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, 1997280304Sjkim 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, 1998280304Sjkim 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, 1999280304Sjkim 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, 2000280304Sjkim 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 2001280304Sjkim}; 2002280304Sjkim 2003280304Sjkimstatic const u8 IV15[] = { 2004280304Sjkim 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, 2005280304Sjkim 0xde, 0xca, 0xf8, 0x88 2006280304Sjkim}; 2007280304Sjkim 2008280304Sjkimstatic const u8 C15[] = { 2009280304Sjkim 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07, 2010280304Sjkim 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d, 2011280304Sjkim 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9, 2012280304Sjkim 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa, 2013280304Sjkim 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d, 2014280304Sjkim 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38, 2015280304Sjkim 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a, 2016280304Sjkim 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad 2017280304Sjkim}; 2018280304Sjkim 2019280304Sjkimstatic const u8 T15[] = { 2020280304Sjkim 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd, 2021280304Sjkim 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c 2022280304Sjkim}; 2023280304Sjkim 2024238384Sjkim/* Test Case 16 */ 2025280304Sjkim# define K16 K15 2026280304Sjkim# define IV16 IV15 2027280304Sjkimstatic const u8 P16[] = { 2028280304Sjkim 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, 2029280304Sjkim 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, 2030280304Sjkim 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, 2031280304Sjkim 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, 2032280304Sjkim 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, 2033280304Sjkim 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, 2034280304Sjkim 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, 2035280304Sjkim 0xba, 0x63, 0x7b, 0x39 2036280304Sjkim}; 2037238384Sjkim 2038280304Sjkimstatic const u8 A16[] = { 2039280304Sjkim 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 2040280304Sjkim 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 2041280304Sjkim 0xab, 0xad, 0xda, 0xd2 2042280304Sjkim}; 2043280304Sjkim 2044280304Sjkimstatic const u8 C16[] = { 2045280304Sjkim 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07, 2046280304Sjkim 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d, 2047280304Sjkim 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9, 2048280304Sjkim 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa, 2049280304Sjkim 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d, 2050280304Sjkim 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38, 2051280304Sjkim 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a, 2052280304Sjkim 0xbc, 0xc9, 0xf6, 0x62 2053280304Sjkim}; 2054280304Sjkim 2055280304Sjkimstatic const u8 T16[] = { 2056280304Sjkim 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68, 2057280304Sjkim 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b 2058280304Sjkim}; 2059280304Sjkim 2060238384Sjkim/* Test Case 17 */ 2061280304Sjkim# define K17 K16 2062280304Sjkim# define P17 P16 2063280304Sjkim# define A17 A16 2064280304Sjkimstatic const u8 IV17[] = { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad }; 2065238384Sjkim 2066280304Sjkimstatic const u8 C17[] = { 2067280304Sjkim 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32, 2068280304Sjkim 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb, 2069280304Sjkim 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa, 2070280304Sjkim 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0, 2071280304Sjkim 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0, 2072280304Sjkim 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78, 2073280304Sjkim 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99, 2074280304Sjkim 0xf4, 0x7c, 0x9b, 0x1f 2075280304Sjkim}; 2076280304Sjkim 2077280304Sjkimstatic const u8 T17[] = { 2078280304Sjkim 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4, 2079280304Sjkim 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 2080280304Sjkim}; 2081280304Sjkim 2082238384Sjkim/* Test Case 18 */ 2083280304Sjkim# define K18 K17 2084280304Sjkim# define P18 P17 2085280304Sjkim# define A18 A17 2086280304Sjkimstatic const u8 IV18[] = { 2087280304Sjkim 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5, 2088280304Sjkim 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa, 2089280304Sjkim 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1, 2090280304Sjkim 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28, 2091280304Sjkim 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39, 2092280304Sjkim 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54, 2093280304Sjkim 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57, 2094280304Sjkim 0xa6, 0x37, 0xb3, 0x9b 2095280304Sjkim}; 2096238384Sjkim 2097280304Sjkimstatic const u8 C18[] = { 2098280304Sjkim 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1, 2099280304Sjkim 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20, 2100280304Sjkim 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19, 2101280304Sjkim 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4, 2102280304Sjkim 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45, 2103280304Sjkim 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde, 2104280304Sjkim 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e, 2105280304Sjkim 0x44, 0xae, 0x7e, 0x3f 2106280304Sjkim}; 2107280304Sjkim 2108280304Sjkimstatic const u8 T18[] = { 2109280304Sjkim 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0, 2110280304Sjkim 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a 2111280304Sjkim}; 2112280304Sjkim 2113264331Sjkim/* Test Case 19 */ 2114280304Sjkim# define K19 K1 2115280304Sjkim# define P19 P1 2116280304Sjkim# define IV19 IV1 2117280304Sjkim# define C19 C1 2118280304Sjkimstatic const u8 A19[] = { 2119280304Sjkim 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, 2120280304Sjkim 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, 2121280304Sjkim 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, 2122280304Sjkim 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, 2123280304Sjkim 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, 2124280304Sjkim 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, 2125280304Sjkim 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, 2126280304Sjkim 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, 2127280304Sjkim 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07, 2128280304Sjkim 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d, 2129280304Sjkim 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9, 2130280304Sjkim 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa, 2131280304Sjkim 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d, 2132280304Sjkim 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38, 2133280304Sjkim 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a, 2134280304Sjkim 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad 2135280304Sjkim}; 2136264331Sjkim 2137280304Sjkimstatic const u8 T19[] = { 2138280304Sjkim 0x5f, 0xea, 0x79, 0x3a, 0x2d, 0x6f, 0x97, 0x4d, 2139280304Sjkim 0x37, 0xe6, 0x8e, 0x0c, 0xb8, 0xff, 0x94, 0x92 2140280304Sjkim}; 2141280304Sjkim 2142264331Sjkim/* Test Case 20 */ 2143280304Sjkim# define K20 K1 2144280304Sjkim# define A20 A1 2145280304Sjkim/* this results in 0xff in counter LSB */ 2146280304Sjkimstatic const u8 IV20[64] = { 0xff, 0xff, 0xff, 0xff }; 2147264331Sjkim 2148280304Sjkimstatic const u8 P20[288]; 2149280304Sjkimstatic const u8 C20[] = { 2150280304Sjkim 0x56, 0xb3, 0x37, 0x3c, 0xa9, 0xef, 0x6e, 0x4a, 2151280304Sjkim 0x2b, 0x64, 0xfe, 0x1e, 0x9a, 0x17, 0xb6, 0x14, 2152280304Sjkim 0x25, 0xf1, 0x0d, 0x47, 0xa7, 0x5a, 0x5f, 0xce, 2153280304Sjkim 0x13, 0xef, 0xc6, 0xbc, 0x78, 0x4a, 0xf2, 0x4f, 2154280304Sjkim 0x41, 0x41, 0xbd, 0xd4, 0x8c, 0xf7, 0xc7, 0x70, 2155280304Sjkim 0x88, 0x7a, 0xfd, 0x57, 0x3c, 0xca, 0x54, 0x18, 2156280304Sjkim 0xa9, 0xae, 0xff, 0xcd, 0x7c, 0x5c, 0xed, 0xdf, 2157280304Sjkim 0xc6, 0xa7, 0x83, 0x97, 0xb9, 0xa8, 0x5b, 0x49, 2158280304Sjkim 0x9d, 0xa5, 0x58, 0x25, 0x72, 0x67, 0xca, 0xab, 2159280304Sjkim 0x2a, 0xd0, 0xb2, 0x3c, 0xa4, 0x76, 0xa5, 0x3c, 2160280304Sjkim 0xb1, 0x7f, 0xb4, 0x1c, 0x4b, 0x8b, 0x47, 0x5c, 2161280304Sjkim 0xb4, 0xf3, 0xf7, 0x16, 0x50, 0x94, 0xc2, 0x29, 2162280304Sjkim 0xc9, 0xe8, 0xc4, 0xdc, 0x0a, 0x2a, 0x5f, 0xf1, 2163280304Sjkim 0x90, 0x3e, 0x50, 0x15, 0x11, 0x22, 0x13, 0x76, 2164280304Sjkim 0xa1, 0xcd, 0xb8, 0x36, 0x4c, 0x50, 0x61, 0xa2, 2165280304Sjkim 0x0c, 0xae, 0x74, 0xbc, 0x4a, 0xcd, 0x76, 0xce, 2166280304Sjkim 0xb0, 0xab, 0xc9, 0xfd, 0x32, 0x17, 0xef, 0x9f, 2167280304Sjkim 0x8c, 0x90, 0xbe, 0x40, 0x2d, 0xdf, 0x6d, 0x86, 2168280304Sjkim 0x97, 0xf4, 0xf8, 0x80, 0xdf, 0xf1, 0x5b, 0xfb, 2169280304Sjkim 0x7a, 0x6b, 0x28, 0x24, 0x1e, 0xc8, 0xfe, 0x18, 2170280304Sjkim 0x3c, 0x2d, 0x59, 0xe3, 0xf9, 0xdf, 0xff, 0x65, 2171280304Sjkim 0x3c, 0x71, 0x26, 0xf0, 0xac, 0xb9, 0xe6, 0x42, 2172280304Sjkim 0x11, 0xf4, 0x2b, 0xae, 0x12, 0xaf, 0x46, 0x2b, 2173280304Sjkim 0x10, 0x70, 0xbe, 0xf1, 0xab, 0x5e, 0x36, 0x06, 2174280304Sjkim 0x87, 0x2c, 0xa1, 0x0d, 0xee, 0x15, 0xb3, 0x24, 2175280304Sjkim 0x9b, 0x1a, 0x1b, 0x95, 0x8f, 0x23, 0x13, 0x4c, 2176280304Sjkim 0x4b, 0xcc, 0xb7, 0xd0, 0x32, 0x00, 0xbc, 0xe4, 2177280304Sjkim 0x20, 0xa2, 0xf8, 0xeb, 0x66, 0xdc, 0xf3, 0x64, 2178280304Sjkim 0x4d, 0x14, 0x23, 0xc1, 0xb5, 0x69, 0x90, 0x03, 2179280304Sjkim 0xc1, 0x3e, 0xce, 0xf4, 0xbf, 0x38, 0xa3, 0xb6, 2180280304Sjkim 0x0e, 0xed, 0xc3, 0x40, 0x33, 0xba, 0xc1, 0x90, 2181280304Sjkim 0x27, 0x83, 0xdc, 0x6d, 0x89, 0xe2, 0xe7, 0x74, 2182280304Sjkim 0x18, 0x8a, 0x43, 0x9c, 0x7e, 0xbc, 0xc0, 0x67, 2183280304Sjkim 0x2d, 0xbd, 0xa4, 0xdd, 0xcf, 0xb2, 0x79, 0x46, 2184280304Sjkim 0x13, 0xb0, 0xbe, 0x41, 0x31, 0x5e, 0xf7, 0x78, 2185280304Sjkim 0x70, 0x8a, 0x70, 0xee, 0x7d, 0x75, 0x16, 0x5c 2186280304Sjkim}; 2187238384Sjkim 2188280304Sjkimstatic const u8 T20[] = { 2189280304Sjkim 0x8b, 0x30, 0x7f, 0x6b, 0x33, 0x28, 0x6d, 0x0a, 2190280304Sjkim 0xb0, 0x26, 0xa9, 0xed, 0x3f, 0xe1, 0xe8, 0x5f 2191280304Sjkim}; 2192280304Sjkim 2193280304Sjkim# define TEST_CASE(n) do { \ 2194280304Sjkim u8 out[sizeof(P##n)]; \ 2195280304Sjkim AES_set_encrypt_key(K##n,sizeof(K##n)*8,&key); \ 2196280304Sjkim CRYPTO_gcm128_init(&ctx,&key,(block128_f)AES_encrypt); \ 2197280304Sjkim CRYPTO_gcm128_setiv(&ctx,IV##n,sizeof(IV##n)); \ 2198280304Sjkim memset(out,0,sizeof(out)); \ 2199280304Sjkim if (A##n) CRYPTO_gcm128_aad(&ctx,A##n,sizeof(A##n)); \ 2200280304Sjkim if (P##n) CRYPTO_gcm128_encrypt(&ctx,P##n,out,sizeof(out)); \ 2201280304Sjkim if (CRYPTO_gcm128_finish(&ctx,T##n,16) || \ 2202280304Sjkim (C##n && memcmp(out,C##n,sizeof(out)))) \ 2203280304Sjkim ret++, printf ("encrypt test#%d failed.\n",n); \ 2204280304Sjkim CRYPTO_gcm128_setiv(&ctx,IV##n,sizeof(IV##n)); \ 2205280304Sjkim memset(out,0,sizeof(out)); \ 2206280304Sjkim if (A##n) CRYPTO_gcm128_aad(&ctx,A##n,sizeof(A##n)); \ 2207280304Sjkim if (C##n) CRYPTO_gcm128_decrypt(&ctx,C##n,out,sizeof(out)); \ 2208280304Sjkim if (CRYPTO_gcm128_finish(&ctx,T##n,16) || \ 2209280304Sjkim (P##n && memcmp(out,P##n,sizeof(out)))) \ 2210280304Sjkim ret++, printf ("decrypt test#%d failed.\n",n); \ 2211280304Sjkim } while(0) 2212280304Sjkim 2213238384Sjkimint main() 2214238384Sjkim{ 2215280304Sjkim GCM128_CONTEXT ctx; 2216280304Sjkim AES_KEY key; 2217280304Sjkim int ret = 0; 2218238384Sjkim 2219280304Sjkim TEST_CASE(1); 2220280304Sjkim TEST_CASE(2); 2221280304Sjkim TEST_CASE(3); 2222280304Sjkim TEST_CASE(4); 2223280304Sjkim TEST_CASE(5); 2224280304Sjkim TEST_CASE(6); 2225280304Sjkim TEST_CASE(7); 2226280304Sjkim TEST_CASE(8); 2227280304Sjkim TEST_CASE(9); 2228280304Sjkim TEST_CASE(10); 2229280304Sjkim TEST_CASE(11); 2230280304Sjkim TEST_CASE(12); 2231280304Sjkim TEST_CASE(13); 2232280304Sjkim TEST_CASE(14); 2233280304Sjkim TEST_CASE(15); 2234280304Sjkim TEST_CASE(16); 2235280304Sjkim TEST_CASE(17); 2236280304Sjkim TEST_CASE(18); 2237280304Sjkim TEST_CASE(19); 2238280304Sjkim TEST_CASE(20); 2239238384Sjkim 2240280304Sjkim# ifdef OPENSSL_CPUID_OBJ 2241280304Sjkim { 2242280304Sjkim size_t start, stop, gcm_t, ctr_t, OPENSSL_rdtsc(); 2243280304Sjkim union { 2244280304Sjkim u64 u; 2245280304Sjkim u8 c[1024]; 2246280304Sjkim } buf; 2247280304Sjkim int i; 2248238384Sjkim 2249280304Sjkim AES_set_encrypt_key(K1, sizeof(K1) * 8, &key); 2250280304Sjkim CRYPTO_gcm128_init(&ctx, &key, (block128_f) AES_encrypt); 2251280304Sjkim CRYPTO_gcm128_setiv(&ctx, IV1, sizeof(IV1)); 2252238384Sjkim 2253280304Sjkim CRYPTO_gcm128_encrypt(&ctx, buf.c, buf.c, sizeof(buf)); 2254280304Sjkim start = OPENSSL_rdtsc(); 2255280304Sjkim CRYPTO_gcm128_encrypt(&ctx, buf.c, buf.c, sizeof(buf)); 2256280304Sjkim gcm_t = OPENSSL_rdtsc() - start; 2257238384Sjkim 2258280304Sjkim CRYPTO_ctr128_encrypt(buf.c, buf.c, sizeof(buf), 2259280304Sjkim &key, ctx.Yi.c, ctx.EKi.c, &ctx.mres, 2260280304Sjkim (block128_f) AES_encrypt); 2261280304Sjkim start = OPENSSL_rdtsc(); 2262280304Sjkim CRYPTO_ctr128_encrypt(buf.c, buf.c, sizeof(buf), 2263280304Sjkim &key, ctx.Yi.c, ctx.EKi.c, &ctx.mres, 2264280304Sjkim (block128_f) AES_encrypt); 2265280304Sjkim ctr_t = OPENSSL_rdtsc() - start; 2266238384Sjkim 2267280304Sjkim printf("%.2f-%.2f=%.2f\n", 2268280304Sjkim gcm_t / (double)sizeof(buf), 2269280304Sjkim ctr_t / (double)sizeof(buf), 2270280304Sjkim (gcm_t - ctr_t) / (double)sizeof(buf)); 2271280304Sjkim# ifdef GHASH 2272280304Sjkim { 2273280304Sjkim void (*gcm_ghash_p) (u64 Xi[2], const u128 Htable[16], 2274280304Sjkim const u8 *inp, size_t len) = ctx.ghash; 2275264331Sjkim 2276280304Sjkim GHASH((&ctx), buf.c, sizeof(buf)); 2277280304Sjkim start = OPENSSL_rdtsc(); 2278280304Sjkim for (i = 0; i < 100; ++i) 2279280304Sjkim GHASH((&ctx), buf.c, sizeof(buf)); 2280280304Sjkim gcm_t = OPENSSL_rdtsc() - start; 2281280304Sjkim printf("%.2f\n", gcm_t / (double)sizeof(buf) / (double)i); 2282280304Sjkim } 2283280304Sjkim# endif 2284280304Sjkim } 2285280304Sjkim# endif 2286238384Sjkim 2287280304Sjkim return ret; 2288238384Sjkim} 2289238384Sjkim#endif 2290