sha512.c 7.85 KB
Newer Older
1
2
/* sha512.c
 *
Niels Möller's avatar
Niels Möller committed
3
 * The sha512 hash function.
4
 *
Niels Möller's avatar
Niels Möller committed
5
 * See http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf
6
7
8
9
 */

/* nettle, low-level cryptographics library
 *
Niels Möller's avatar
Niels Möller committed
10
 * Copyright (C) 2001, 2010 Niels Möller
11
 * Copyright (C) 2014 Joachim Strömbergson
12
13
14
15
16
17
18
19
20
21
22
23
24
 *  
 * The nettle library is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or (at your
 * option) any later version.
 *
 * The nettle library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 * License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with the nettle library; see the file COPYING.LIB.  If not, write to
25
26
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02111-1301, USA.
27
28
29
30
31
32
33
34
35
36
37
38
 */

/* Modelled after the sha1.c code by Peter Gutmann. */

#if HAVE_CONFIG_H
# include "config.h"
#endif

#include <assert.h>
#include <stdlib.h>
#include <string.h>

39
#include "sha2.h"
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74

#include "macros.h"

/* Generated by the gp script

     {
       print("obase=16");
       for (i = 1,80,
         root = prime(i)^(1/3);
         fraction = root - floor(root);
         print(floor(2^64 * fraction));
       );
       quit();
     }

   piped through

     |grep -v '^[' | bc \
       |awk '{printf("0x%sULL,%s", $1, NR%3 == 0 ? "\n" : "");}'

   to convert it to hex.
*/

static const uint64_t
K[80] =
{
  0x428A2F98D728AE22ULL,0x7137449123EF65CDULL,
  0xB5C0FBCFEC4D3B2FULL,0xE9B5DBA58189DBBCULL,
  0x3956C25BF348B538ULL,0x59F111F1B605D019ULL,
  0x923F82A4AF194F9BULL,0xAB1C5ED5DA6D8118ULL,
  0xD807AA98A3030242ULL,0x12835B0145706FBEULL,
  0x243185BE4EE4B28CULL,0x550C7DC3D5FFB4E2ULL,
  0x72BE5D74F27B896FULL,0x80DEB1FE3B1696B1ULL,
  0x9BDC06A725C71235ULL,0xC19BF174CF692694ULL,
  0xE49B69C19EF14AD2ULL,0xEFBE4786384F25E3ULL,
Niels Möller's avatar
Niels Möller committed
75
  0x0FC19DC68B8CD5B5ULL,0x240CA1CC77AC9C65ULL,
76
77
78
79
80
  0x2DE92C6F592B0275ULL,0x4A7484AA6EA6E483ULL,
  0x5CB0A9DCBD41FBD4ULL,0x76F988DA831153B5ULL,
  0x983E5152EE66DFABULL,0xA831C66D2DB43210ULL,
  0xB00327C898FB213FULL,0xBF597FC7BEEF0EE4ULL,
  0xC6E00BF33DA88FC2ULL,0xD5A79147930AA725ULL,
Niels Möller's avatar
Niels Möller committed
81
  0x06CA6351E003826FULL,0x142929670A0E6E70ULL,
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
  0x27B70A8546D22FFCULL,0x2E1B21385C26C926ULL,
  0x4D2C6DFC5AC42AEDULL,0x53380D139D95B3DFULL,
  0x650A73548BAF63DEULL,0x766A0ABB3C77B2A8ULL,
  0x81C2C92E47EDAEE6ULL,0x92722C851482353BULL,
  0xA2BFE8A14CF10364ULL,0xA81A664BBC423001ULL,
  0xC24B8B70D0F89791ULL,0xC76C51A30654BE30ULL,
  0xD192E819D6EF5218ULL,0xD69906245565A910ULL,
  0xF40E35855771202AULL,0x106AA07032BBD1B8ULL,
  0x19A4C116B8D2D0C8ULL,0x1E376C085141AB53ULL,
  0x2748774CDF8EEB99ULL,0x34B0BCB5E19B48A8ULL,
  0x391C0CB3C5C95A63ULL,0x4ED8AA4AE3418ACBULL,
  0x5B9CCA4F7763E373ULL,0x682E6FF3D6B2B8A3ULL,
  0x748F82EE5DEFB2FCULL,0x78A5636F43172F60ULL,
  0x84C87814A1F0AB72ULL,0x8CC702081A6439ECULL,
  0x90BEFFFA23631E28ULL,0xA4506CEBDE82BDE9ULL,
  0xBEF9A3F7B2C67915ULL,0xC67178F2E372532BULL,
  0xCA273ECEEA26619CULL,0xD186B8C721C0C207ULL,
  0xEADA7DD6CDE0EB1EULL,0xF57D4F7FEE6ED178ULL,
Niels Möller's avatar
Niels Möller committed
100
  0x06F067AA72176FBAULL,0x0A637DC5A2C898A6ULL,
101
102
103
104
105
106
107
  0x113F9804BEF90DAEULL,0x1B710B35131C471BULL,
  0x28DB77F523047D84ULL,0x32CAAB7B40C72493ULL,
  0x3C9EBE0A15C9BEBCULL,0x431D67C49C100D4CULL,
  0x4CC5D4BECB3E42B6ULL,0x597F299CFC657E2AULL,
  0x5FCB6FAB3AD6FAECULL,0x6C44198C4A475817ULL,
};

108
#define COMPRESS(ctx, data) (_nettle_sha512_compress((ctx)->state, (data), K))
109

110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
void
sha512_init(struct sha512_ctx *ctx)
{
  /* Initial values, generated by the gp script
       {
         for (i = 1,8,
	   root = prime(i)^(1/2);
	   fraction = root - floor(root);
	   print(floor(2^64 * fraction));
	 );
       }
. */
  static const uint64_t H0[_SHA512_DIGEST_LENGTH] =
  {
    0x6A09E667F3BCC908ULL,0xBB67AE8584CAA73BULL,
    0x3C6EF372FE94F82BULL,0xA54FF53A5F1D36F1ULL,
    0x510E527FADE682D1ULL,0x9B05688C2B3E6C1FULL,
    0x1F83D9ABFB41BD6BULL,0x5BE0CD19137E2179ULL,
  };

  memcpy(ctx->state, H0, sizeof(H0));

  /* Initialize bit count */
  ctx->count_low = ctx->count_high = 0;
  
  /* Initialize buffer */
  ctx->index = 0;
}

void
sha512_update(struct sha512_ctx *ctx,
141
	      size_t length, const uint8_t *data)
142
{
143
  MD_UPDATE (ctx, length, data, COMPRESS, MD_INCR(ctx));
144
145
}

146
147
static void
sha512_write_digest(struct sha512_ctx *ctx,
148
		    size_t length,
149
		    uint8_t *digest)
150
{
151
152
  uint64_t high, low;

153
154
155
  unsigned i;
  unsigned words;
  unsigned leftover;
156
157

  assert(length <= SHA512_DIGEST_SIZE);
158
159
160
161
162
163
164
165
166
167
168
169
170
171

  MD_PAD(ctx, 16, COMPRESS);

  /* There are 1024 = 2^10 bits in one block */  
  high = (ctx->count_high << 10) | (ctx->count_low >> 54);
  low = (ctx->count_low << 10) | (ctx->index << 3);

  /* This is slightly inefficient, as the numbers are converted to
     big-endian format, and will be converted back by the compression
     function. It's probably not worth the effort to fix this. */
  WRITE_UINT64(ctx->block + (SHA512_DATA_SIZE - 16), high);
  WRITE_UINT64(ctx->block + (SHA512_DATA_SIZE - 8), low);
  COMPRESS(ctx, ctx->block);

172
173
174
175
176
177
178
179
  words = length / 8;
  leftover = length % 8;

  for (i = 0; i < words; i++, digest += 8)
    WRITE_UINT64(digest, ctx->state[i]);

  if (leftover)
    {
180
181
182
183
184
185
186
      /* Truncate to the right size */
      uint64_t word = ctx->state[i] >> (8*(8 - leftover));

      do {
	digest[--leftover] = word & 0xff;
	word >>= 8;
      } while (leftover);
187
    }
188
}
189

190
191
void
sha512_digest(struct sha512_ctx *ctx,
192
	      size_t length,
193
194
195
196
197
	      uint8_t *digest)
{
  assert(length <= SHA512_DIGEST_SIZE);

  sha512_write_digest(ctx, length, digest);
198
199
  sha512_init(ctx);
}
200

201
/* sha384 variant. */
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
void
sha384_init(struct sha512_ctx *ctx)
{
  /* Initial values, generated by the gp script
       {
         for (i = 9,16,
	   root = prime(i)^(1/2);
	   fraction = root - floor(root);
	   print(floor(2^64 * fraction));
	 );
       }
. */
  static const uint64_t H0[_SHA512_DIGEST_LENGTH] =
  {
    0xCBBB9D5DC1059ED8ULL, 0x629A292A367CD507ULL,
    0x9159015A3070DD17ULL, 0x152FECD8F70E5939ULL,
    0x67332667FFC00B31ULL, 0x8EB44A8768581511ULL,
    0xDB0C2E0D64F98FA7ULL, 0x47B5481DBEFA4FA4ULL,
  };

  memcpy(ctx->state, H0, sizeof(H0));

  /* Initialize bit count */
  ctx->count_low = ctx->count_high = 0;
  
  /* Initialize buffer */
  ctx->index = 0;
}

void
sha384_digest(struct sha512_ctx *ctx,
233
	      size_t length,
234
235
236
237
238
239
240
	      uint8_t *digest)
{
  assert(length <= SHA384_DIGEST_SIZE);

  sha512_write_digest(ctx, length, digest);
  sha384_init(ctx);
}
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304


/* sha-512/224 variant. */
void
sha512_224_init(struct sha512_ctx *ctx)
{
  static const uint64_t H0[_SHA512_DIGEST_LENGTH] =
  {
    0x8c3d37c819544da2ULL, 0x73e1996689dcd4d6ULL,
    0x1dfab7ae32ff9c82ULL, 0x679dd514582f9fcfULL,
    0x0f6d2b697bd44da8ULL, 0x77e36f7304c48942ULL,
    0x3f9d85a86a1d36c8ULL, 0x1112e6ad91d692a1ULL,
  };

  memcpy(ctx->state, H0, sizeof(H0));

  /* Initialize bit count */
  ctx->count_low = ctx->count_high = 0;
  
  /* Initialize buffer */
  ctx->index = 0;
}

void
sha512_224_digest(struct sha512_ctx *ctx,
	      size_t length,
	      uint8_t *digest)
{
  assert(length <= SHA224_DIGEST_SIZE);

  sha512_write_digest(ctx, length, digest);
  sha512_224_init(ctx);
}


/* sha-512/256 variant. */
void
sha512_256_init(struct sha512_ctx *ctx)
{
  static const uint64_t H0[_SHA512_DIGEST_LENGTH] =
    {
      0x22312194fc2bf72cULL, 0x9f555fa3c84c64c2ULL, 
      0x2393b86b6f53b151ULL, 0x963877195940eabdULL, 
      0x96283ee2a88effe3ULL, 0xbe5e1e2553863992ULL, 
      0x2b0199fc2c85b8aaULL, 0x0eb72ddc81c52ca2ULL,
    };

  memcpy(ctx->state, H0, sizeof(H0));

  /* Initialize bit count */
  ctx->count_low = ctx->count_high = 0;
  
  /* Initialize buffer */
  ctx->index = 0;
}

void
sha512_256_digest(struct sha512_ctx *ctx,
	      size_t length,
	      uint8_t *digest)
{
  assert(length <= SHA256_DIGEST_SIZE);

  sha512_write_digest(ctx, length, digest);
305
  sha512_256_init(ctx);
306
}