LCOV - code coverage report
Current view: top level - cipher - sha512.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 321 0.0 %
Date: 2016-12-15 12:59:22 Functions: 0 14 0.0 %

          Line data    Source code
       1             : /* sha512.c - SHA384 and SHA512 hash functions
       2             :  * Copyright (C) 2003, 2008, 2009 Free Software Foundation, Inc.
       3             :  *
       4             :  * This file is part of Libgcrypt.
       5             :  *
       6             :  * Libgcrypt is free software; you can redistribute it and/or modify
       7             :  * it under the terms of the GNU Lesser general Public License as
       8             :  * published by the Free Software Foundation; either version 2.1 of
       9             :  * the License, or (at your option) any later version.
      10             :  *
      11             :  * Libgcrypt is distributed in the hope that it will be useful,
      12             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             :  * GNU Lesser General Public License for more details.
      15             :  *
      16             :  * You should have received a copy of the GNU Lesser General Public
      17             :  * License along with this program; if not, see <http://www.gnu.org/licenses/>.
      18             :  */
      19             : 
      20             : 
      21             : /*  Test vectors from FIPS-180-2:
      22             :  *
      23             :  *  "abc"
      24             :  * 384:
      25             :  *  CB00753F 45A35E8B B5A03D69 9AC65007 272C32AB 0EDED163
      26             :  *  1A8B605A 43FF5BED 8086072B A1E7CC23 58BAECA1 34C825A7
      27             :  * 512:
      28             :  *  DDAF35A1 93617ABA CC417349 AE204131 12E6FA4E 89A97EA2 0A9EEEE6 4B55D39A
      29             :  *  2192992A 274FC1A8 36BA3C23 A3FEEBBD 454D4423 643CE80E 2A9AC94F A54CA49F
      30             :  *
      31             :  *  "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"
      32             :  * 384:
      33             :  *  09330C33 F71147E8 3D192FC7 82CD1B47 53111B17 3B3B05D2
      34             :  *  2FA08086 E3B0F712 FCC7C71A 557E2DB9 66C3E9FA 91746039
      35             :  * 512:
      36             :  *  8E959B75 DAE313DA 8CF4F728 14FC143F 8F7779C6 EB9F7FA1 7299AEAD B6889018
      37             :  *  501D289E 4900F7E4 331B99DE C4B5433A C7D329EE B6DD2654 5E96E55B 874BE909
      38             :  *
      39             :  *  "a" x 1000000
      40             :  * 384:
      41             :  *  9D0E1809 716474CB 086E834E 310A4A1C ED149E9C 00F24852
      42             :  *  7972CEC5 704C2A5B 07B8B3DC 38ECC4EB AE97DDD8 7F3D8985
      43             :  * 512:
      44             :  *  E718483D 0CE76964 4E2E42C7 BC15B463 8E1F98B1 3B204428 5632A803 AFA973EB
      45             :  *  DE0FF244 877EA60A 4CB0432C E577C31B EB009C5C 2C49AA2E 4EADB217 AD8CC09B
      46             :  */
      47             : 
      48             : 
      49             : #include <config.h>
      50             : #include <string.h>
      51             : #include "g10lib.h"
      52             : #include "bithelp.h"
      53             : #include "bufhelp.h"
      54             : #include "cipher.h"
      55             : #include "hash-common.h"
      56             : 
      57             : 
      58             : /* USE_ARM_NEON_ASM indicates whether to enable ARM NEON assembly code. */
      59             : #undef USE_ARM_NEON_ASM
      60             : #ifdef ENABLE_NEON_SUPPORT
      61             : # if defined(HAVE_ARM_ARCH_V6) && defined(__ARMEL__) \
      62             :      && defined(HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS) \
      63             :      && defined(HAVE_GCC_INLINE_ASM_NEON)
      64             : #  define USE_ARM_NEON_ASM 1
      65             : # endif
      66             : #endif /*ENABLE_NEON_SUPPORT*/
      67             : 
      68             : 
      69             : /* USE_ARM_ASM indicates whether to enable ARM assembly code. */
      70             : #undef USE_ARM_ASM
      71             : #if defined(__ARMEL__) && defined(HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS)
      72             : # define USE_ARM_ASM 1
      73             : #endif
      74             : 
      75             : 
      76             : /* USE_SSSE3 indicates whether to compile with Intel SSSE3 code. */
      77             : #undef USE_SSSE3
      78             : #if defined(__x86_64__) && defined(HAVE_GCC_INLINE_ASM_SSSE3) && \
      79             :     defined(HAVE_INTEL_SYNTAX_PLATFORM_AS) && \
      80             :     (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
      81             :      defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
      82             : # define USE_SSSE3 1
      83             : #endif
      84             : 
      85             : 
      86             : /* USE_AVX indicates whether to compile with Intel AVX code. */
      87             : #undef USE_AVX
      88             : #if defined(__x86_64__) && defined(HAVE_GCC_INLINE_ASM_AVX) && \
      89             :     defined(HAVE_INTEL_SYNTAX_PLATFORM_AS) && \
      90             :     (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
      91             :      defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
      92             : # define USE_AVX 1
      93             : #endif
      94             : 
      95             : 
      96             : /* USE_AVX2 indicates whether to compile with Intel AVX2/rorx code. */
      97             : #undef USE_AVX2
      98             : #if defined(__x86_64__) && defined(HAVE_GCC_INLINE_ASM_AVX2) && \
      99             :     defined(HAVE_GCC_INLINE_ASM_BMI2) && \
     100             :     defined(HAVE_INTEL_SYNTAX_PLATFORM_AS) && \
     101             :     (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
     102             :      defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
     103             : # define USE_AVX2 1
     104             : #endif
     105             : 
     106             : 
     107             : typedef struct
     108             : {
     109             :   u64 h0, h1, h2, h3, h4, h5, h6, h7;
     110             : } SHA512_STATE;
     111             : 
     112             : typedef struct
     113             : {
     114             :   gcry_md_block_ctx_t bctx;
     115             :   SHA512_STATE state;
     116             : #ifdef USE_ARM_NEON_ASM
     117             :   unsigned int use_neon:1;
     118             : #endif
     119             : #ifdef USE_SSSE3
     120             :   unsigned int use_ssse3:1;
     121             : #endif
     122             : #ifdef USE_AVX
     123             :   unsigned int use_avx:1;
     124             : #endif
     125             : #ifdef USE_AVX2
     126             :   unsigned int use_avx2:1;
     127             : #endif
     128             : } SHA512_CONTEXT;
     129             : 
     130             : static unsigned int
     131             : transform (void *context, const unsigned char *data, size_t nblks);
     132             : 
     133             : static void
     134           0 : sha512_init (void *context, unsigned int flags)
     135             : {
     136           0 :   SHA512_CONTEXT *ctx = context;
     137           0 :   SHA512_STATE *hd = &ctx->state;
     138           0 :   unsigned int features = _gcry_get_hw_features ();
     139             : 
     140             :   (void)flags;
     141             : 
     142           0 :   hd->h0 = U64_C(0x6a09e667f3bcc908);
     143           0 :   hd->h1 = U64_C(0xbb67ae8584caa73b);
     144           0 :   hd->h2 = U64_C(0x3c6ef372fe94f82b);
     145           0 :   hd->h3 = U64_C(0xa54ff53a5f1d36f1);
     146           0 :   hd->h4 = U64_C(0x510e527fade682d1);
     147           0 :   hd->h5 = U64_C(0x9b05688c2b3e6c1f);
     148           0 :   hd->h6 = U64_C(0x1f83d9abfb41bd6b);
     149           0 :   hd->h7 = U64_C(0x5be0cd19137e2179);
     150             : 
     151           0 :   ctx->bctx.nblocks = 0;
     152           0 :   ctx->bctx.nblocks_high = 0;
     153           0 :   ctx->bctx.count = 0;
     154           0 :   ctx->bctx.blocksize = 128;
     155           0 :   ctx->bctx.bwrite = transform;
     156             : 
     157             : #ifdef USE_ARM_NEON_ASM
     158             :   ctx->use_neon = (features & HWF_ARM_NEON) != 0;
     159             : #endif
     160             : #ifdef USE_SSSE3
     161           0 :   ctx->use_ssse3 = (features & HWF_INTEL_SSSE3) != 0;
     162             : #endif
     163             : #ifdef USE_AVX
     164           0 :   ctx->use_avx = (features & HWF_INTEL_AVX) && (features & HWF_INTEL_FAST_SHLD);
     165             : #endif
     166             : #ifdef USE_AVX2
     167           0 :   ctx->use_avx2 = (features & HWF_INTEL_AVX2) && (features & HWF_INTEL_BMI2);
     168             : #endif
     169             : 
     170             :   (void)features;
     171           0 : }
     172             : 
     173             : static void
     174           0 : sha384_init (void *context, unsigned int flags)
     175             : {
     176           0 :   SHA512_CONTEXT *ctx = context;
     177           0 :   SHA512_STATE *hd = &ctx->state;
     178           0 :   unsigned int features = _gcry_get_hw_features ();
     179             : 
     180             :   (void)flags;
     181             : 
     182           0 :   hd->h0 = U64_C(0xcbbb9d5dc1059ed8);
     183           0 :   hd->h1 = U64_C(0x629a292a367cd507);
     184           0 :   hd->h2 = U64_C(0x9159015a3070dd17);
     185           0 :   hd->h3 = U64_C(0x152fecd8f70e5939);
     186           0 :   hd->h4 = U64_C(0x67332667ffc00b31);
     187           0 :   hd->h5 = U64_C(0x8eb44a8768581511);
     188           0 :   hd->h6 = U64_C(0xdb0c2e0d64f98fa7);
     189           0 :   hd->h7 = U64_C(0x47b5481dbefa4fa4);
     190             : 
     191           0 :   ctx->bctx.nblocks = 0;
     192           0 :   ctx->bctx.nblocks_high = 0;
     193           0 :   ctx->bctx.count = 0;
     194           0 :   ctx->bctx.blocksize = 128;
     195           0 :   ctx->bctx.bwrite = transform;
     196             : 
     197             : #ifdef USE_ARM_NEON_ASM
     198             :   ctx->use_neon = (features & HWF_ARM_NEON) != 0;
     199             : #endif
     200             : #ifdef USE_SSSE3
     201           0 :   ctx->use_ssse3 = (features & HWF_INTEL_SSSE3) != 0;
     202             : #endif
     203             : #ifdef USE_AVX
     204           0 :   ctx->use_avx = (features & HWF_INTEL_AVX) && (features & HWF_INTEL_FAST_SHLD);
     205             : #endif
     206             : #ifdef USE_AVX2
     207           0 :   ctx->use_avx2 = (features & HWF_INTEL_AVX2) && (features & HWF_INTEL_BMI2);
     208             : #endif
     209             : 
     210             :   (void)features;
     211           0 : }
     212             : 
     213             : 
     214             : static const u64 k[] =
     215             :   {
     216             :     U64_C(0x428a2f98d728ae22), U64_C(0x7137449123ef65cd),
     217             :     U64_C(0xb5c0fbcfec4d3b2f), U64_C(0xe9b5dba58189dbbc),
     218             :     U64_C(0x3956c25bf348b538), U64_C(0x59f111f1b605d019),
     219             :     U64_C(0x923f82a4af194f9b), U64_C(0xab1c5ed5da6d8118),
     220             :     U64_C(0xd807aa98a3030242), U64_C(0x12835b0145706fbe),
     221             :     U64_C(0x243185be4ee4b28c), U64_C(0x550c7dc3d5ffb4e2),
     222             :     U64_C(0x72be5d74f27b896f), U64_C(0x80deb1fe3b1696b1),
     223             :     U64_C(0x9bdc06a725c71235), U64_C(0xc19bf174cf692694),
     224             :     U64_C(0xe49b69c19ef14ad2), U64_C(0xefbe4786384f25e3),
     225             :     U64_C(0x0fc19dc68b8cd5b5), U64_C(0x240ca1cc77ac9c65),
     226             :     U64_C(0x2de92c6f592b0275), U64_C(0x4a7484aa6ea6e483),
     227             :     U64_C(0x5cb0a9dcbd41fbd4), U64_C(0x76f988da831153b5),
     228             :     U64_C(0x983e5152ee66dfab), U64_C(0xa831c66d2db43210),
     229             :     U64_C(0xb00327c898fb213f), U64_C(0xbf597fc7beef0ee4),
     230             :     U64_C(0xc6e00bf33da88fc2), U64_C(0xd5a79147930aa725),
     231             :     U64_C(0x06ca6351e003826f), U64_C(0x142929670a0e6e70),
     232             :     U64_C(0x27b70a8546d22ffc), U64_C(0x2e1b21385c26c926),
     233             :     U64_C(0x4d2c6dfc5ac42aed), U64_C(0x53380d139d95b3df),
     234             :     U64_C(0x650a73548baf63de), U64_C(0x766a0abb3c77b2a8),
     235             :     U64_C(0x81c2c92e47edaee6), U64_C(0x92722c851482353b),
     236             :     U64_C(0xa2bfe8a14cf10364), U64_C(0xa81a664bbc423001),
     237             :     U64_C(0xc24b8b70d0f89791), U64_C(0xc76c51a30654be30),
     238             :     U64_C(0xd192e819d6ef5218), U64_C(0xd69906245565a910),
     239             :     U64_C(0xf40e35855771202a), U64_C(0x106aa07032bbd1b8),
     240             :     U64_C(0x19a4c116b8d2d0c8), U64_C(0x1e376c085141ab53),
     241             :     U64_C(0x2748774cdf8eeb99), U64_C(0x34b0bcb5e19b48a8),
     242             :     U64_C(0x391c0cb3c5c95a63), U64_C(0x4ed8aa4ae3418acb),
     243             :     U64_C(0x5b9cca4f7763e373), U64_C(0x682e6ff3d6b2b8a3),
     244             :     U64_C(0x748f82ee5defb2fc), U64_C(0x78a5636f43172f60),
     245             :     U64_C(0x84c87814a1f0ab72), U64_C(0x8cc702081a6439ec),
     246             :     U64_C(0x90befffa23631e28), U64_C(0xa4506cebde82bde9),
     247             :     U64_C(0xbef9a3f7b2c67915), U64_C(0xc67178f2e372532b),
     248             :     U64_C(0xca273eceea26619c), U64_C(0xd186b8c721c0c207),
     249             :     U64_C(0xeada7dd6cde0eb1e), U64_C(0xf57d4f7fee6ed178),
     250             :     U64_C(0x06f067aa72176fba), U64_C(0x0a637dc5a2c898a6),
     251             :     U64_C(0x113f9804bef90dae), U64_C(0x1b710b35131c471b),
     252             :     U64_C(0x28db77f523047d84), U64_C(0x32caab7b40c72493),
     253             :     U64_C(0x3c9ebe0a15c9bebc), U64_C(0x431d67c49c100d4c),
     254             :     U64_C(0x4cc5d4becb3e42b6), U64_C(0x597f299cfc657e2a),
     255             :     U64_C(0x5fcb6fab3ad6faec), U64_C(0x6c44198c4a475817)
     256             :   };
     257             : 
     258             : #ifndef USE_ARM_ASM
     259             : 
     260             : static inline u64
     261           0 : ROTR (u64 x, u64 n)
     262             : {
     263           0 :   return ((x >> n) | (x << (64 - n)));
     264             : }
     265             : 
     266             : static inline u64
     267           0 : Ch (u64 x, u64 y, u64 z)
     268             : {
     269           0 :   return ((x & y) ^ ( ~x & z));
     270             : }
     271             : 
     272             : static inline u64
     273           0 : Maj (u64 x, u64 y, u64 z)
     274             : {
     275           0 :   return ((x & y) ^ (x & z) ^ (y & z));
     276             : }
     277             : 
     278             : static inline u64
     279           0 : Sum0 (u64 x)
     280             : {
     281           0 :   return (ROTR (x, 28) ^ ROTR (x, 34) ^ ROTR (x, 39));
     282             : }
     283             : 
     284             : static inline u64
     285           0 : Sum1 (u64 x)
     286             : {
     287           0 :   return (ROTR (x, 14) ^ ROTR (x, 18) ^ ROTR (x, 41));
     288             : }
     289             : 
     290             : /****************
     291             :  * Transform the message W which consists of 16 64-bit-words
     292             :  */
     293             : static unsigned int
     294           0 : transform_blk (SHA512_STATE *hd, const unsigned char *data)
     295             : {
     296             :   u64 a, b, c, d, e, f, g, h;
     297             :   u64 w[16];
     298             :   int t;
     299             : 
     300             :   /* get values from the chaining vars */
     301           0 :   a = hd->h0;
     302           0 :   b = hd->h1;
     303           0 :   c = hd->h2;
     304           0 :   d = hd->h3;
     305           0 :   e = hd->h4;
     306           0 :   f = hd->h5;
     307           0 :   g = hd->h6;
     308           0 :   h = hd->h7;
     309             : 
     310           0 :   for ( t = 0; t < 16; t++ )
     311           0 :     w[t] = buf_get_be64(data + t * 8);
     312             : 
     313             : #define S0(x) (ROTR((x),1) ^ ROTR((x),8) ^ ((x)>>7))
     314             : #define S1(x) (ROTR((x),19) ^ ROTR((x),61) ^ ((x)>>6))
     315             : 
     316           0 :   for (t = 0; t < 80 - 16; )
     317             :     {
     318             :       u64 t1, t2;
     319             : 
     320             :       /* Performance on a AMD Athlon(tm) Dual Core Processor 4050e
     321             :          with gcc 4.3.3 using gcry_md_hash_buffer of each 10000 bytes
     322             :          initialized to 0,1,2,3...255,0,... and 1000 iterations:
     323             : 
     324             :          Not unrolled with macros:  440ms
     325             :          Unrolled with macros:      350ms
     326             :          Unrolled with inline:      330ms
     327             :       */
     328             : #if 0 /* Not unrolled.  */
     329             :       t1 = h + Sum1 (e) + Ch (e, f, g) + k[t] + w[t%16];
     330             :       w[t%16] += S1 (w[(t - 2)%16]) + w[(t - 7)%16] + S0 (w[(t - 15)%16]);
     331             :       t2 = Sum0 (a) + Maj (a, b, c);
     332             :       h = g;
     333             :       g = f;
     334             :       f = e;
     335             :       e = d + t1;
     336             :       d = c;
     337             :       c = b;
     338             :       b = a;
     339             :       a = t1 + t2;
     340             :       t++;
     341             : #else /* Unrolled to interweave the chain variables.  */
     342           0 :       t1 = h + Sum1 (e) + Ch (e, f, g) + k[t] + w[0];
     343           0 :       w[0] += S1 (w[14]) + w[9] + S0 (w[1]);
     344           0 :       t2 = Sum0 (a) + Maj (a, b, c);
     345           0 :       d += t1;
     346           0 :       h = t1 + t2;
     347             : 
     348           0 :       t1 = g + Sum1 (d) + Ch (d, e, f) + k[t+1] + w[1];
     349           0 :       w[1] += S1 (w[15]) + w[10] + S0 (w[2]);
     350           0 :       t2 = Sum0 (h) + Maj (h, a, b);
     351           0 :       c += t1;
     352           0 :       g  = t1 + t2;
     353             : 
     354           0 :       t1 = f + Sum1 (c) + Ch (c, d, e) + k[t+2] + w[2];
     355           0 :       w[2] += S1 (w[0]) + w[11] + S0 (w[3]);
     356           0 :       t2 = Sum0 (g) + Maj (g, h, a);
     357           0 :       b += t1;
     358           0 :       f  = t1 + t2;
     359             : 
     360           0 :       t1 = e + Sum1 (b) + Ch (b, c, d) + k[t+3] + w[3];
     361           0 :       w[3] += S1 (w[1]) + w[12] + S0 (w[4]);
     362           0 :       t2 = Sum0 (f) + Maj (f, g, h);
     363           0 :       a += t1;
     364           0 :       e  = t1 + t2;
     365             : 
     366           0 :       t1 = d + Sum1 (a) + Ch (a, b, c) + k[t+4] + w[4];
     367           0 :       w[4] += S1 (w[2]) + w[13] + S0 (w[5]);
     368           0 :       t2 = Sum0 (e) + Maj (e, f, g);
     369           0 :       h += t1;
     370           0 :       d  = t1 + t2;
     371             : 
     372           0 :       t1 = c + Sum1 (h) + Ch (h, a, b) + k[t+5] + w[5];
     373           0 :       w[5] += S1 (w[3]) + w[14] + S0 (w[6]);
     374           0 :       t2 = Sum0 (d) + Maj (d, e, f);
     375           0 :       g += t1;
     376           0 :       c  = t1 + t2;
     377             : 
     378           0 :       t1 = b + Sum1 (g) + Ch (g, h, a) + k[t+6] + w[6];
     379           0 :       w[6] += S1 (w[4]) + w[15] + S0 (w[7]);
     380           0 :       t2 = Sum0 (c) + Maj (c, d, e);
     381           0 :       f += t1;
     382           0 :       b  = t1 + t2;
     383             : 
     384           0 :       t1 = a + Sum1 (f) + Ch (f, g, h) + k[t+7] + w[7];
     385           0 :       w[7] += S1 (w[5]) + w[0] + S0 (w[8]);
     386           0 :       t2 = Sum0 (b) + Maj (b, c, d);
     387           0 :       e += t1;
     388           0 :       a  = t1 + t2;
     389             : 
     390           0 :       t1 = h + Sum1 (e) + Ch (e, f, g) + k[t+8] + w[8];
     391           0 :       w[8] += S1 (w[6]) + w[1] + S0 (w[9]);
     392           0 :       t2 = Sum0 (a) + Maj (a, b, c);
     393           0 :       d += t1;
     394           0 :       h  = t1 + t2;
     395             : 
     396           0 :       t1 = g + Sum1 (d) + Ch (d, e, f) + k[t+9] + w[9];
     397           0 :       w[9] += S1 (w[7]) + w[2] + S0 (w[10]);
     398           0 :       t2 = Sum0 (h) + Maj (h, a, b);
     399           0 :       c += t1;
     400           0 :       g  = t1 + t2;
     401             : 
     402           0 :       t1 = f + Sum1 (c) + Ch (c, d, e) + k[t+10] + w[10];
     403           0 :       w[10] += S1 (w[8]) + w[3] + S0 (w[11]);
     404           0 :       t2 = Sum0 (g) + Maj (g, h, a);
     405           0 :       b += t1;
     406           0 :       f  = t1 + t2;
     407             : 
     408           0 :       t1 = e + Sum1 (b) + Ch (b, c, d) + k[t+11] + w[11];
     409           0 :       w[11] += S1 (w[9]) + w[4] + S0 (w[12]);
     410           0 :       t2 = Sum0 (f) + Maj (f, g, h);
     411           0 :       a += t1;
     412           0 :       e  = t1 + t2;
     413             : 
     414           0 :       t1 = d + Sum1 (a) + Ch (a, b, c) + k[t+12] + w[12];
     415           0 :       w[12] += S1 (w[10]) + w[5] + S0 (w[13]);
     416           0 :       t2 = Sum0 (e) + Maj (e, f, g);
     417           0 :       h += t1;
     418           0 :       d  = t1 + t2;
     419             : 
     420           0 :       t1 = c + Sum1 (h) + Ch (h, a, b) + k[t+13] + w[13];
     421           0 :       w[13] += S1 (w[11]) + w[6] + S0 (w[14]);
     422           0 :       t2 = Sum0 (d) + Maj (d, e, f);
     423           0 :       g += t1;
     424           0 :       c  = t1 + t2;
     425             : 
     426           0 :       t1 = b + Sum1 (g) + Ch (g, h, a) + k[t+14] + w[14];
     427           0 :       w[14] += S1 (w[12]) + w[7] + S0 (w[15]);
     428           0 :       t2 = Sum0 (c) + Maj (c, d, e);
     429           0 :       f += t1;
     430           0 :       b  = t1 + t2;
     431             : 
     432           0 :       t1 = a + Sum1 (f) + Ch (f, g, h) + k[t+15] + w[15];
     433           0 :       w[15] += S1 (w[13]) + w[8] + S0 (w[0]);
     434           0 :       t2 = Sum0 (b) + Maj (b, c, d);
     435           0 :       e += t1;
     436           0 :       a  = t1 + t2;
     437             : 
     438           0 :       t += 16;
     439             : #endif
     440             :     }
     441             : 
     442           0 :   for (; t < 80; )
     443             :     {
     444             :       u64 t1, t2;
     445             : 
     446             : #if 0 /* Not unrolled.  */
     447             :       t1 = h + Sum1 (e) + Ch (e, f, g) + k[t] + w[t%16];
     448             :       t2 = Sum0 (a) + Maj (a, b, c);
     449             :       h = g;
     450             :       g = f;
     451             :       f = e;
     452             :       e = d + t1;
     453             :       d = c;
     454             :       c = b;
     455             :       b = a;
     456             :       a = t1 + t2;
     457             :       t++;
     458             : #else /* Unrolled to interweave the chain variables.  */
     459           0 :       t1 = h + Sum1 (e) + Ch (e, f, g) + k[t] + w[0];
     460           0 :       t2 = Sum0 (a) + Maj (a, b, c);
     461           0 :       d += t1;
     462           0 :       h  = t1 + t2;
     463             : 
     464           0 :       t1 = g + Sum1 (d) + Ch (d, e, f) + k[t+1] + w[1];
     465           0 :       t2 = Sum0 (h) + Maj (h, a, b);
     466           0 :       c += t1;
     467           0 :       g  = t1 + t2;
     468             : 
     469           0 :       t1 = f + Sum1 (c) + Ch (c, d, e) + k[t+2] + w[2];
     470           0 :       t2 = Sum0 (g) + Maj (g, h, a);
     471           0 :       b += t1;
     472           0 :       f  = t1 + t2;
     473             : 
     474           0 :       t1 = e + Sum1 (b) + Ch (b, c, d) + k[t+3] + w[3];
     475           0 :       t2 = Sum0 (f) + Maj (f, g, h);
     476           0 :       a += t1;
     477           0 :       e  = t1 + t2;
     478             : 
     479           0 :       t1 = d + Sum1 (a) + Ch (a, b, c) + k[t+4] + w[4];
     480           0 :       t2 = Sum0 (e) + Maj (e, f, g);
     481           0 :       h += t1;
     482           0 :       d  = t1 + t2;
     483             : 
     484           0 :       t1 = c + Sum1 (h) + Ch (h, a, b) + k[t+5] + w[5];
     485           0 :       t2 = Sum0 (d) + Maj (d, e, f);
     486           0 :       g += t1;
     487           0 :       c  = t1 + t2;
     488             : 
     489           0 :       t1 = b + Sum1 (g) + Ch (g, h, a) + k[t+6] + w[6];
     490           0 :       t2 = Sum0 (c) + Maj (c, d, e);
     491           0 :       f += t1;
     492           0 :       b  = t1 + t2;
     493             : 
     494           0 :       t1 = a + Sum1 (f) + Ch (f, g, h) + k[t+7] + w[7];
     495           0 :       t2 = Sum0 (b) + Maj (b, c, d);
     496           0 :       e += t1;
     497           0 :       a  = t1 + t2;
     498             : 
     499           0 :       t1 = h + Sum1 (e) + Ch (e, f, g) + k[t+8] + w[8];
     500           0 :       t2 = Sum0 (a) + Maj (a, b, c);
     501           0 :       d += t1;
     502           0 :       h  = t1 + t2;
     503             : 
     504           0 :       t1 = g + Sum1 (d) + Ch (d, e, f) + k[t+9] + w[9];
     505           0 :       t2 = Sum0 (h) + Maj (h, a, b);
     506           0 :       c += t1;
     507           0 :       g  = t1 + t2;
     508             : 
     509           0 :       t1 = f + Sum1 (c) + Ch (c, d, e) + k[t+10] + w[10];
     510           0 :       t2 = Sum0 (g) + Maj (g, h, a);
     511           0 :       b += t1;
     512           0 :       f  = t1 + t2;
     513             : 
     514           0 :       t1 = e + Sum1 (b) + Ch (b, c, d) + k[t+11] + w[11];
     515           0 :       t2 = Sum0 (f) + Maj (f, g, h);
     516           0 :       a += t1;
     517           0 :       e  = t1 + t2;
     518             : 
     519           0 :       t1 = d + Sum1 (a) + Ch (a, b, c) + k[t+12] + w[12];
     520           0 :       t2 = Sum0 (e) + Maj (e, f, g);
     521           0 :       h += t1;
     522           0 :       d  = t1 + t2;
     523             : 
     524           0 :       t1 = c + Sum1 (h) + Ch (h, a, b) + k[t+13] + w[13];
     525           0 :       t2 = Sum0 (d) + Maj (d, e, f);
     526           0 :       g += t1;
     527           0 :       c  = t1 + t2;
     528             : 
     529           0 :       t1 = b + Sum1 (g) + Ch (g, h, a) + k[t+14] + w[14];
     530           0 :       t2 = Sum0 (c) + Maj (c, d, e);
     531           0 :       f += t1;
     532           0 :       b  = t1 + t2;
     533             : 
     534           0 :       t1 = a + Sum1 (f) + Ch (f, g, h) + k[t+15] + w[15];
     535           0 :       t2 = Sum0 (b) + Maj (b, c, d);
     536           0 :       e += t1;
     537           0 :       a  = t1 + t2;
     538             : 
     539           0 :       t += 16;
     540             : #endif
     541             :     }
     542             : 
     543             :   /* Update chaining vars.  */
     544           0 :   hd->h0 += a;
     545           0 :   hd->h1 += b;
     546           0 :   hd->h2 += c;
     547           0 :   hd->h3 += d;
     548           0 :   hd->h4 += e;
     549           0 :   hd->h5 += f;
     550           0 :   hd->h6 += g;
     551           0 :   hd->h7 += h;
     552             : 
     553           0 :   return /* burn_stack */ (8 + 16) * sizeof(u64) + sizeof(u32) +
     554             :                           3 * sizeof(void*);
     555             : }
     556             : #endif /*!USE_ARM_ASM*/
     557             : 
     558             : /* AMD64 assembly implementations use SystemV ABI, ABI conversion and additional
     559             :  * stack to store XMM6-XMM15 needed on Win64. */
     560             : #undef ASM_FUNC_ABI
     561             : #undef ASM_EXTRA_STACK
     562             : #if defined(USE_SSSE3) || defined(USE_AVX) || defined(USE_AVX2)
     563             : # ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
     564             : #  define ASM_FUNC_ABI __attribute__((sysv_abi))
     565             : #  define ASM_EXTRA_STACK (10 * 16)
     566             : # else
     567             : #  define ASM_FUNC_ABI
     568             : #  define ASM_EXTRA_STACK 0
     569             : # endif
     570             : #endif
     571             : 
     572             : 
     573             : #ifdef USE_ARM_NEON_ASM
     574             : void _gcry_sha512_transform_armv7_neon (SHA512_STATE *hd,
     575             :                                         const unsigned char *data,
     576             :                                         const u64 k[], size_t num_blks);
     577             : #endif
     578             : 
     579             : #ifdef USE_ARM_ASM
     580             : unsigned int _gcry_sha512_transform_arm (SHA512_STATE *hd,
     581             :                                          const unsigned char *data,
     582             :                                          const u64 k[], size_t num_blks);
     583             : #endif
     584             : 
     585             : #ifdef USE_SSSE3
     586             : unsigned int _gcry_sha512_transform_amd64_ssse3(const void *input_data,
     587             :                                                 void *state,
     588             :                                                 size_t num_blks) ASM_FUNC_ABI;
     589             : #endif
     590             : 
     591             : #ifdef USE_AVX
     592             : unsigned int _gcry_sha512_transform_amd64_avx(const void *input_data,
     593             :                                               void *state,
     594             :                                               size_t num_blks) ASM_FUNC_ABI;
     595             : #endif
     596             : 
     597             : #ifdef USE_AVX2
     598             : unsigned int _gcry_sha512_transform_amd64_avx2(const void *input_data,
     599             :                                                void *state,
     600             :                                                size_t num_blks) ASM_FUNC_ABI;
     601             : #endif
     602             : 
     603             : 
     604             : static unsigned int
     605           0 : transform (void *context, const unsigned char *data, size_t nblks)
     606             : {
     607           0 :   SHA512_CONTEXT *ctx = context;
     608             :   unsigned int burn;
     609             : 
     610             : #ifdef USE_AVX2
     611           0 :   if (ctx->use_avx2)
     612           0 :     return _gcry_sha512_transform_amd64_avx2 (data, &ctx->state, nblks)
     613           0 :            + 4 * sizeof(void*) + ASM_EXTRA_STACK;
     614             : #endif
     615             : 
     616             : #ifdef USE_AVX
     617           0 :   if (ctx->use_avx)
     618           0 :     return _gcry_sha512_transform_amd64_avx (data, &ctx->state, nblks)
     619           0 :            + 4 * sizeof(void*) + ASM_EXTRA_STACK;
     620             : #endif
     621             : 
     622             : #ifdef USE_SSSE3
     623           0 :   if (ctx->use_ssse3)
     624           0 :     return _gcry_sha512_transform_amd64_ssse3 (data, &ctx->state, nblks)
     625           0 :            + 4 * sizeof(void*) + ASM_EXTRA_STACK;
     626             : #endif
     627             : 
     628             : #ifdef USE_ARM_NEON_ASM
     629             :   if (ctx->use_neon)
     630             :     {
     631             :       _gcry_sha512_transform_armv7_neon (&ctx->state, data, k, nblks);
     632             : 
     633             :       /* _gcry_sha512_transform_armv7_neon does not store sensitive data
     634             :        * to stack.  */
     635             :       return /* no burn_stack */ 0;
     636             :     }
     637             : #endif
     638             : 
     639             : #ifdef USE_ARM_ASM
     640             :   burn = _gcry_sha512_transform_arm (&ctx->state, data, k, nblks);
     641             : #else
     642             :   do
     643             :     {
     644           0 :       burn = transform_blk (&ctx->state, data) + 3 * sizeof(void*);
     645           0 :       data += 128;
     646             :     }
     647           0 :   while (--nblks);
     648             : 
     649             : #ifdef ASM_EXTRA_STACK
     650             :   /* 'transform_blk' is typically inlined and XMM6-XMM15 are stored at
     651             :    *  the prologue of this function. Therefore need to add ASM_EXTRA_STACK to
     652             :    *  here too.
     653             :    */
     654           0 :   burn += ASM_EXTRA_STACK;
     655             : #endif
     656             : #endif
     657             : 
     658           0 :   return burn;
     659             : }
     660             : 
     661             : 
     662             : /* The routine final terminates the computation and
     663             :  * returns the digest.
     664             :  * The handle is prepared for a new cycle, but adding bytes to the
     665             :  * handle will the destroy the returned buffer.
     666             :  * Returns: 64 bytes representing the digest.  When used for sha384,
     667             :  * we take the leftmost 48 of those bytes.
     668             :  */
     669             : 
     670             : static void
     671           0 : sha512_final (void *context)
     672             : {
     673           0 :   SHA512_CONTEXT *hd = context;
     674             :   unsigned int stack_burn_depth;
     675             :   u64 t, th, msb, lsb;
     676             :   byte *p;
     677             : 
     678           0 :   _gcry_md_block_write (context, NULL, 0); /* flush */ ;
     679             : 
     680           0 :   t = hd->bctx.nblocks;
     681             :   /* if (sizeof t == sizeof hd->bctx.nblocks) */
     682           0 :   th = hd->bctx.nblocks_high;
     683             :   /* else */
     684             :   /*   th = hd->bctx.nblocks >> 64; In case we ever use u128  */
     685             : 
     686             :   /* multiply by 128 to make a byte count */
     687           0 :   lsb = t << 7;
     688           0 :   msb = (th << 7) | (t >> 57);
     689             :   /* add the count */
     690           0 :   t = lsb;
     691           0 :   if ((lsb += hd->bctx.count) < t)
     692           0 :     msb++;
     693             :   /* multiply by 8 to make a bit count */
     694           0 :   t = lsb;
     695           0 :   lsb <<= 3;
     696           0 :   msb <<= 3;
     697           0 :   msb |= t >> 61;
     698             : 
     699           0 :   if (hd->bctx.count < 112)
     700             :     {                           /* enough room */
     701           0 :       hd->bctx.buf[hd->bctx.count++] = 0x80;      /* pad */
     702           0 :       while (hd->bctx.count < 112)
     703           0 :         hd->bctx.buf[hd->bctx.count++] = 0;       /* pad */
     704             :     }
     705             :   else
     706             :     {                           /* need one extra block */
     707           0 :       hd->bctx.buf[hd->bctx.count++] = 0x80;      /* pad character */
     708           0 :       while (hd->bctx.count < 128)
     709           0 :         hd->bctx.buf[hd->bctx.count++] = 0;
     710           0 :       _gcry_md_block_write (context, NULL, 0); /* flush */ ;
     711           0 :       memset (hd->bctx.buf, 0, 112); /* fill next block with zeroes */
     712             :     }
     713             :   /* append the 128 bit count */
     714           0 :   buf_put_be64(hd->bctx.buf + 112, msb);
     715           0 :   buf_put_be64(hd->bctx.buf + 120, lsb);
     716           0 :   stack_burn_depth = transform (hd, hd->bctx.buf, 1);
     717           0 :   _gcry_burn_stack (stack_burn_depth);
     718             : 
     719           0 :   p = hd->bctx.buf;
     720             : #define X(a) do { buf_put_be64(p, hd->state.h##a); p += 8; } while (0)
     721           0 :   X (0);
     722           0 :   X (1);
     723           0 :   X (2);
     724           0 :   X (3);
     725           0 :   X (4);
     726           0 :   X (5);
     727             :   /* Note that these last two chunks are included even for SHA384.
     728             :      We just ignore them. */
     729           0 :   X (6);
     730           0 :   X (7);
     731             : #undef X
     732           0 : }
     733             : 
     734             : static byte *
     735           0 : sha512_read (void *context)
     736             : {
     737           0 :   SHA512_CONTEXT *hd = (SHA512_CONTEXT *) context;
     738           0 :   return hd->bctx.buf;
     739             : }
     740             : 
     741             : 
     742             : 
     743             : /*
     744             :      Self-test section.
     745             :  */
     746             : 
     747             : 
     748             : static gpg_err_code_t
     749           0 : selftests_sha384 (int extended, selftest_report_func_t report)
     750             : {
     751             :   const char *what;
     752             :   const char *errtxt;
     753             : 
     754           0 :   what = "short string";
     755           0 :   errtxt = _gcry_hash_selftest_check_one
     756             :     (GCRY_MD_SHA384, 0,
     757             :      "abc", 3,
     758             :      "\xcb\x00\x75\x3f\x45\xa3\x5e\x8b\xb5\xa0\x3d\x69\x9a\xc6\x50\x07"
     759             :      "\x27\x2c\x32\xab\x0e\xde\xd1\x63\x1a\x8b\x60\x5a\x43\xff\x5b\xed"
     760             :      "\x80\x86\x07\x2b\xa1\xe7\xcc\x23\x58\xba\xec\xa1\x34\xc8\x25\xa7", 48);
     761           0 :   if (errtxt)
     762           0 :     goto failed;
     763             : 
     764           0 :   if (extended)
     765             :     {
     766           0 :       what = "long string";
     767           0 :       errtxt = _gcry_hash_selftest_check_one
     768             :         (GCRY_MD_SHA384, 0,
     769             :          "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
     770             :          "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", 112,
     771             :          "\x09\x33\x0C\x33\xF7\x11\x47\xE8\x3D\x19\x2F\xC7\x82\xCD\x1B\x47"
     772             :          "\x53\x11\x1B\x17\x3B\x3B\x05\xD2\x2F\xA0\x80\x86\xE3\xB0\xF7\x12"
     773             :          "\xFC\xC7\xC7\x1A\x55\x7E\x2D\xB9\x66\xC3\xE9\xFA\x91\x74\x60\x39",
     774             :          48);
     775           0 :       if (errtxt)
     776           0 :         goto failed;
     777             : 
     778           0 :       what = "one million \"a\"";
     779           0 :       errtxt = _gcry_hash_selftest_check_one
     780             :         (GCRY_MD_SHA384, 1,
     781             :          NULL, 0,
     782             :          "\x9D\x0E\x18\x09\x71\x64\x74\xCB\x08\x6E\x83\x4E\x31\x0A\x4A\x1C"
     783             :          "\xED\x14\x9E\x9C\x00\xF2\x48\x52\x79\x72\xCE\xC5\x70\x4C\x2A\x5B"
     784             :          "\x07\xB8\xB3\xDC\x38\xEC\xC4\xEB\xAE\x97\xDD\xD8\x7F\x3D\x89\x85",
     785             :          48);
     786           0 :       if (errtxt)
     787           0 :         goto failed;
     788             :     }
     789             : 
     790           0 :   return 0; /* Succeeded. */
     791             : 
     792             :  failed:
     793           0 :   if (report)
     794           0 :     report ("digest", GCRY_MD_SHA384, what, errtxt);
     795           0 :   return GPG_ERR_SELFTEST_FAILED;
     796             : }
     797             : 
     798             : static gpg_err_code_t
     799           0 : selftests_sha512 (int extended, selftest_report_func_t report)
     800             : {
     801             :   const char *what;
     802             :   const char *errtxt;
     803             : 
     804           0 :   what = "short string";
     805           0 :   errtxt = _gcry_hash_selftest_check_one
     806             :     (GCRY_MD_SHA512, 0,
     807             :      "abc", 3,
     808             :      "\xDD\xAF\x35\xA1\x93\x61\x7A\xBA\xCC\x41\x73\x49\xAE\x20\x41\x31"
     809             :      "\x12\xE6\xFA\x4E\x89\xA9\x7E\xA2\x0A\x9E\xEE\xE6\x4B\x55\xD3\x9A"
     810             :      "\x21\x92\x99\x2A\x27\x4F\xC1\xA8\x36\xBA\x3C\x23\xA3\xFE\xEB\xBD"
     811             :      "\x45\x4D\x44\x23\x64\x3C\xE8\x0E\x2A\x9A\xC9\x4F\xA5\x4C\xA4\x9F", 64);
     812           0 :   if (errtxt)
     813           0 :     goto failed;
     814             : 
     815           0 :   if (extended)
     816             :     {
     817           0 :       what = "long string";
     818           0 :       errtxt = _gcry_hash_selftest_check_one
     819             :         (GCRY_MD_SHA512, 0,
     820             :          "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
     821             :          "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", 112,
     822             :          "\x8E\x95\x9B\x75\xDA\xE3\x13\xDA\x8C\xF4\xF7\x28\x14\xFC\x14\x3F"
     823             :          "\x8F\x77\x79\xC6\xEB\x9F\x7F\xA1\x72\x99\xAE\xAD\xB6\x88\x90\x18"
     824             :          "\x50\x1D\x28\x9E\x49\x00\xF7\xE4\x33\x1B\x99\xDE\xC4\xB5\x43\x3A"
     825             :          "\xC7\xD3\x29\xEE\xB6\xDD\x26\x54\x5E\x96\xE5\x5B\x87\x4B\xE9\x09",
     826             :          64);
     827           0 :       if (errtxt)
     828           0 :         goto failed;
     829             : 
     830           0 :       what = "one million \"a\"";
     831           0 :       errtxt = _gcry_hash_selftest_check_one
     832             :         (GCRY_MD_SHA512, 1,
     833             :          NULL, 0,
     834             :          "\xE7\x18\x48\x3D\x0C\xE7\x69\x64\x4E\x2E\x42\xC7\xBC\x15\xB4\x63"
     835             :          "\x8E\x1F\x98\xB1\x3B\x20\x44\x28\x56\x32\xA8\x03\xAF\xA9\x73\xEB"
     836             :          "\xDE\x0F\xF2\x44\x87\x7E\xA6\x0A\x4C\xB0\x43\x2C\xE5\x77\xC3\x1B"
     837             :          "\xEB\x00\x9C\x5C\x2C\x49\xAA\x2E\x4E\xAD\xB2\x17\xAD\x8C\xC0\x9B",
     838             :          64);
     839           0 :       if (errtxt)
     840           0 :         goto failed;
     841             :     }
     842             : 
     843           0 :   return 0; /* Succeeded. */
     844             : 
     845             :  failed:
     846           0 :   if (report)
     847           0 :     report ("digest", GCRY_MD_SHA512, what, errtxt);
     848           0 :   return GPG_ERR_SELFTEST_FAILED;
     849             : }
     850             : 
     851             : 
     852             : /* Run a full self-test for ALGO and return 0 on success.  */
     853             : static gpg_err_code_t
     854           0 : run_selftests (int algo, int extended, selftest_report_func_t report)
     855             : {
     856             :   gpg_err_code_t ec;
     857             : 
     858           0 :   switch (algo)
     859             :     {
     860             :     case GCRY_MD_SHA384:
     861           0 :       ec = selftests_sha384 (extended, report);
     862           0 :       break;
     863             :     case GCRY_MD_SHA512:
     864           0 :       ec = selftests_sha512 (extended, report);
     865           0 :       break;
     866             :     default:
     867           0 :       ec = GPG_ERR_DIGEST_ALGO;
     868           0 :       break;
     869             : 
     870             :     }
     871           0 :   return ec;
     872             : }
     873             : 
     874             : 
     875             : 
     876             : 
     877             : static byte sha512_asn[] =      /* Object ID is 2.16.840.1.101.3.4.2.3 */
     878             :   {
     879             :     0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
     880             :     0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05,
     881             :     0x00, 0x04, 0x40
     882             :   };
     883             : 
     884             : static gcry_md_oid_spec_t oid_spec_sha512[] =
     885             :   {
     886             :     { "2.16.840.1.101.3.4.2.3" },
     887             : 
     888             :     /* PKCS#1 sha512WithRSAEncryption */
     889             :     { "1.2.840.113549.1.1.13" },
     890             : 
     891             :     { NULL }
     892             :   };
     893             : 
     894             : gcry_md_spec_t _gcry_digest_spec_sha512 =
     895             :   {
     896             :     GCRY_MD_SHA512, {0, 1},
     897             :     "SHA512", sha512_asn, DIM (sha512_asn), oid_spec_sha512, 64,
     898             :     sha512_init, _gcry_md_block_write, sha512_final, sha512_read, NULL,
     899             :     sizeof (SHA512_CONTEXT),
     900             :     run_selftests
     901             :   };
     902             : 
     903             : static byte sha384_asn[] =      /* Object ID is 2.16.840.1.101.3.4.2.2 */
     904             :   {
     905             :     0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
     906             :     0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05,
     907             :     0x00, 0x04, 0x30
     908             :   };
     909             : 
     910             : static gcry_md_oid_spec_t oid_spec_sha384[] =
     911             :   {
     912             :     { "2.16.840.1.101.3.4.2.2" },
     913             : 
     914             :     /* PKCS#1 sha384WithRSAEncryption */
     915             :     { "1.2.840.113549.1.1.12" },
     916             : 
     917             :     { NULL },
     918             :   };
     919             : 
     920             : gcry_md_spec_t _gcry_digest_spec_sha384 =
     921             :   {
     922             :     GCRY_MD_SHA384, {0, 1},
     923             :     "SHA384", sha384_asn, DIM (sha384_asn), oid_spec_sha384, 48,
     924             :     sha384_init, _gcry_md_block_write, sha512_final, sha512_read, NULL,
     925             :     sizeof (SHA512_CONTEXT),
     926             :     run_selftests
     927             :   };

Generated by: LCOV version 1.12