FFmpeg
sha512.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2007 Michael Niedermayer <michaelni@gmx.at>
3  * Copyright (C) 2009 Konstantin Shishkov
4  * Copyright (C) 2013 James Almer
5  * based on BSD-licensed SHA-2 code by Aaron D. Gifford
6  *
7  * This file is part of FFmpeg.
8  *
9  * FFmpeg is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * FFmpeg is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with FFmpeg; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  */
23 
24 #include <string.h>
25 
26 #include "attributes.h"
27 #include "avutil.h"
28 #include "bswap.h"
29 #include "sha512.h"
30 #include "intreadwrite.h"
31 #include "mem.h"
32 
33 /** hash context */
34 typedef struct AVSHA512 {
35  uint8_t digest_len; ///< digest length in 64-bit words
36  uint64_t count; ///< number of bytes in buffer
37  uint8_t buffer[128]; ///< 1024-bit buffer of input values used in hash updating
38  uint64_t state[8]; ///< current hash value
39 } AVSHA512;
40 
41 const int av_sha512_size = sizeof(AVSHA512);
42 
44 {
45  return av_mallocz(sizeof(struct AVSHA512));
46 }
47 
48 static const uint64_t K512[80] = {
49  UINT64_C(0x428a2f98d728ae22), UINT64_C(0x7137449123ef65cd),
50  UINT64_C(0xb5c0fbcfec4d3b2f), UINT64_C(0xe9b5dba58189dbbc),
51  UINT64_C(0x3956c25bf348b538), UINT64_C(0x59f111f1b605d019),
52  UINT64_C(0x923f82a4af194f9b), UINT64_C(0xab1c5ed5da6d8118),
53  UINT64_C(0xd807aa98a3030242), UINT64_C(0x12835b0145706fbe),
54  UINT64_C(0x243185be4ee4b28c), UINT64_C(0x550c7dc3d5ffb4e2),
55  UINT64_C(0x72be5d74f27b896f), UINT64_C(0x80deb1fe3b1696b1),
56  UINT64_C(0x9bdc06a725c71235), UINT64_C(0xc19bf174cf692694),
57  UINT64_C(0xe49b69c19ef14ad2), UINT64_C(0xefbe4786384f25e3),
58  UINT64_C(0x0fc19dc68b8cd5b5), UINT64_C(0x240ca1cc77ac9c65),
59  UINT64_C(0x2de92c6f592b0275), UINT64_C(0x4a7484aa6ea6e483),
60  UINT64_C(0x5cb0a9dcbd41fbd4), UINT64_C(0x76f988da831153b5),
61  UINT64_C(0x983e5152ee66dfab), UINT64_C(0xa831c66d2db43210),
62  UINT64_C(0xb00327c898fb213f), UINT64_C(0xbf597fc7beef0ee4),
63  UINT64_C(0xc6e00bf33da88fc2), UINT64_C(0xd5a79147930aa725),
64  UINT64_C(0x06ca6351e003826f), UINT64_C(0x142929670a0e6e70),
65  UINT64_C(0x27b70a8546d22ffc), UINT64_C(0x2e1b21385c26c926),
66  UINT64_C(0x4d2c6dfc5ac42aed), UINT64_C(0x53380d139d95b3df),
67  UINT64_C(0x650a73548baf63de), UINT64_C(0x766a0abb3c77b2a8),
68  UINT64_C(0x81c2c92e47edaee6), UINT64_C(0x92722c851482353b),
69  UINT64_C(0xa2bfe8a14cf10364), UINT64_C(0xa81a664bbc423001),
70  UINT64_C(0xc24b8b70d0f89791), UINT64_C(0xc76c51a30654be30),
71  UINT64_C(0xd192e819d6ef5218), UINT64_C(0xd69906245565a910),
72  UINT64_C(0xf40e35855771202a), UINT64_C(0x106aa07032bbd1b8),
73  UINT64_C(0x19a4c116b8d2d0c8), UINT64_C(0x1e376c085141ab53),
74  UINT64_C(0x2748774cdf8eeb99), UINT64_C(0x34b0bcb5e19b48a8),
75  UINT64_C(0x391c0cb3c5c95a63), UINT64_C(0x4ed8aa4ae3418acb),
76  UINT64_C(0x5b9cca4f7763e373), UINT64_C(0x682e6ff3d6b2b8a3),
77  UINT64_C(0x748f82ee5defb2fc), UINT64_C(0x78a5636f43172f60),
78  UINT64_C(0x84c87814a1f0ab72), UINT64_C(0x8cc702081a6439ec),
79  UINT64_C(0x90befffa23631e28), UINT64_C(0xa4506cebde82bde9),
80  UINT64_C(0xbef9a3f7b2c67915), UINT64_C(0xc67178f2e372532b),
81  UINT64_C(0xca273eceea26619c), UINT64_C(0xd186b8c721c0c207),
82  UINT64_C(0xeada7dd6cde0eb1e), UINT64_C(0xf57d4f7fee6ed178),
83  UINT64_C(0x06f067aa72176fba), UINT64_C(0x0a637dc5a2c898a6),
84  UINT64_C(0x113f9804bef90dae), UINT64_C(0x1b710b35131c471b),
85  UINT64_C(0x28db77f523047d84), UINT64_C(0x32caab7b40c72493),
86  UINT64_C(0x3c9ebe0a15c9bebc), UINT64_C(0x431d67c49c100d4c),
87  UINT64_C(0x4cc5d4becb3e42b6), UINT64_C(0x597f299cfc657e2a),
88  UINT64_C(0x5fcb6fab3ad6faec), UINT64_C(0x6c44198c4a475817),
89 };
90 
91 #define ror(value, bits) (((value) >> (bits)) | ((value) << (64 - (bits))))
92 
93 #define Ch(x,y,z) (((x) & ((y) ^ (z))) ^ (z))
94 #define Maj(z,y,x) ((((x) | (y)) & (z)) | ((x) & (y)))
95 
96 #define Sigma0_512(x) (ror((x), 28) ^ ror((x), 34) ^ ror((x), 39))
97 #define Sigma1_512(x) (ror((x), 14) ^ ror((x), 18) ^ ror((x), 41))
98 #define sigma0_512(x) (ror((x), 1) ^ ror((x), 8) ^ ((x) >> 7))
99 #define sigma1_512(x) (ror((x), 19) ^ ror((x), 61) ^ ((x) >> 6))
100 
101 #define blk0(i) (block[i] = AV_RB64(buffer + 8 * (i)))
102 #define blk(i) (block[i] = block[i - 16] + sigma0_512(block[i - 15]) + \
103  sigma1_512(block[i - 2]) + block[i - 7])
104 
105 #define ROUND512(a,b,c,d,e,f,g,h) \
106  T1 += (h) + Sigma1_512(e) + Ch((e), (f), (g)) + K512[i]; \
107  (d) += T1; \
108  (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \
109  i++
110 
111 #define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) \
112  T1 = blk0(i); \
113  ROUND512(a,b,c,d,e,f,g,h)
114 
115 #define ROUND512_16_TO_80(a,b,c,d,e,f,g,h) \
116  T1 = blk(i); \
117  ROUND512(a,b,c,d,e,f,g,h)
118 
119 static void sha512_transform(uint64_t *state, const uint8_t buffer[128])
120 {
121  uint64_t a, b, c, d, e, f, g, h;
122  uint64_t block[80];
123  uint64_t T1;
124  int i;
125 
126  a = state[0];
127  b = state[1];
128  c = state[2];
129  d = state[3];
130  e = state[4];
131  f = state[5];
132  g = state[6];
133  h = state[7];
134 #if CONFIG_SMALL
135  for (i = 0; i < 80; i++) {
136  uint64_t T2;
137  if (i < 16)
138  T1 = blk0(i);
139  else
140  T1 = blk(i);
141  T1 += h + Sigma1_512(e) + Ch(e, f, g) + K512[i];
142  T2 = Sigma0_512(a) + Maj(a, b, c);
143  h = g;
144  g = f;
145  f = e;
146  e = d + T1;
147  d = c;
148  c = b;
149  b = a;
150  a = T1 + T2;
151  }
152 #else
153 
154 #define R512_0 \
155  ROUND512_0_TO_15(a, b, c, d, e, f, g, h); \
156  ROUND512_0_TO_15(h, a, b, c, d, e, f, g); \
157  ROUND512_0_TO_15(g, h, a, b, c, d, e, f); \
158  ROUND512_0_TO_15(f, g, h, a, b, c, d, e); \
159  ROUND512_0_TO_15(e, f, g, h, a, b, c, d); \
160  ROUND512_0_TO_15(d, e, f, g, h, a, b, c); \
161  ROUND512_0_TO_15(c, d, e, f, g, h, a, b); \
162  ROUND512_0_TO_15(b, c, d, e, f, g, h, a)
163 
164  i = 0;
165  R512_0; R512_0;
166 
167 #define R512_16 \
168  ROUND512_16_TO_80(a, b, c, d, e, f, g, h); \
169  ROUND512_16_TO_80(h, a, b, c, d, e, f, g); \
170  ROUND512_16_TO_80(g, h, a, b, c, d, e, f); \
171  ROUND512_16_TO_80(f, g, h, a, b, c, d, e); \
172  ROUND512_16_TO_80(e, f, g, h, a, b, c, d); \
173  ROUND512_16_TO_80(d, e, f, g, h, a, b, c); \
174  ROUND512_16_TO_80(c, d, e, f, g, h, a, b); \
175  ROUND512_16_TO_80(b, c, d, e, f, g, h, a)
176 
179 #endif
180  state[0] += a;
181  state[1] += b;
182  state[2] += c;
183  state[3] += d;
184  state[4] += e;
185  state[5] += f;
186  state[6] += g;
187  state[7] += h;
188 }
189 
190 
192 {
193  ctx->digest_len = bits >> 6;
194  switch (bits) {
195  case 224: // SHA-512/224
196  ctx->state[0] = UINT64_C(0x8C3D37C819544DA2);
197  ctx->state[1] = UINT64_C(0x73E1996689DCD4D6);
198  ctx->state[2] = UINT64_C(0x1DFAB7AE32FF9C82);
199  ctx->state[3] = UINT64_C(0x679DD514582F9FCF);
200  ctx->state[4] = UINT64_C(0x0F6D2B697BD44DA8);
201  ctx->state[5] = UINT64_C(0x77E36F7304C48942);
202  ctx->state[6] = UINT64_C(0x3F9D85A86A1D36C8);
203  ctx->state[7] = UINT64_C(0x1112E6AD91D692A1);
204  break;
205  case 256: // SHA-512/256
206  ctx->state[0] = UINT64_C(0x22312194FC2BF72C);
207  ctx->state[1] = UINT64_C(0x9F555FA3C84C64C2);
208  ctx->state[2] = UINT64_C(0x2393B86B6F53B151);
209  ctx->state[3] = UINT64_C(0x963877195940EABD);
210  ctx->state[4] = UINT64_C(0x96283EE2A88EFFE3);
211  ctx->state[5] = UINT64_C(0xBE5E1E2553863992);
212  ctx->state[6] = UINT64_C(0x2B0199FC2C85B8AA);
213  ctx->state[7] = UINT64_C(0x0EB72DDC81C52CA2);
214  break;
215  case 384: // SHA-384
216  ctx->state[0] = UINT64_C(0xCBBB9D5DC1059ED8);
217  ctx->state[1] = UINT64_C(0x629A292A367CD507);
218  ctx->state[2] = UINT64_C(0x9159015A3070DD17);
219  ctx->state[3] = UINT64_C(0x152FECD8F70E5939);
220  ctx->state[4] = UINT64_C(0x67332667FFC00B31);
221  ctx->state[5] = UINT64_C(0x8EB44A8768581511);
222  ctx->state[6] = UINT64_C(0xDB0C2E0D64F98FA7);
223  ctx->state[7] = UINT64_C(0x47B5481DBEFA4FA4);
224  break;
225  case 512: // SHA-512
226  ctx->state[0] = UINT64_C(0x6A09E667F3BCC908);
227  ctx->state[1] = UINT64_C(0xBB67AE8584CAA73B);
228  ctx->state[2] = UINT64_C(0x3C6EF372FE94F82B);
229  ctx->state[3] = UINT64_C(0xA54FF53A5F1D36F1);
230  ctx->state[4] = UINT64_C(0x510E527FADE682D1);
231  ctx->state[5] = UINT64_C(0x9B05688C2B3E6C1F);
232  ctx->state[6] = UINT64_C(0x1F83D9ABFB41BD6B);
233  ctx->state[7] = UINT64_C(0x5BE0CD19137E2179);
234  break;
235  default:
236  return AVERROR(EINVAL);
237  }
238  ctx->count = 0;
239  return 0;
240 }
241 
242 #if FF_API_CRYPTO_SIZE_T
243 void av_sha512_update(AVSHA512* ctx, const uint8_t* data, unsigned int len)
244 #else
245 void av_sha512_update(AVSHA512* ctx, const uint8_t* data, size_t len)
246 #endif
247 {
248  unsigned int i, j;
249 
250  j = ctx->count & 127;
251  ctx->count += len;
252 #if CONFIG_SMALL
253  for (i = 0; i < len; i++) {
254  ctx->buffer[j++] = data[i];
255  if (128 == j) {
256  sha512_transform(ctx->state, ctx->buffer);
257  j = 0;
258  }
259  }
260 #else
261  if ((j + len) > 127) {
262  memcpy(&ctx->buffer[j], data, (i = 128 - j));
263  sha512_transform(ctx->state, ctx->buffer);
264  for (; i + 127 < len; i += 128)
265  sha512_transform(ctx->state, &data[i]);
266  j = 0;
267  } else
268  i = 0;
269  memcpy(&ctx->buffer[j], &data[i], len - i);
270 #endif
271 }
272 
273 void av_sha512_final(AVSHA512* ctx, uint8_t *digest)
274 {
275  uint64_t i = 0;
276  uint64_t finalcount = av_be2ne64(ctx->count << 3);
277 
278  av_sha512_update(ctx, "\200", 1);
279  while ((ctx->count & 127) != 112)
280  av_sha512_update(ctx, "", 1);
281  av_sha512_update(ctx, (uint8_t *)&i, 8);
282  av_sha512_update(ctx, (uint8_t *)&finalcount, 8); /* Should cause a transform() */
283  for (i = 0; i < ctx->digest_len; i++)
284  AV_WB64(digest + i*8, ctx->state[i]);
285  if (ctx->digest_len & 1) /* SHA512/224 is 28 bytes, and is not divisible by 8. */
286  AV_WB32(digest + i*8, ctx->state[i] >> 32);
287 }
#define blk(i)
Definition: sha512.c:102
uint8_t buffer[128]
1024-bit buffer of input values used in hash updating
Definition: sha512.c:37
ptrdiff_t const GLvoid * data
Definition: opengl_enc.c:100
Memory handling functions.
static const uint64_t K512[80]
Definition: sha512.c:48
const char * g
Definition: vf_curves.c:115
hash context
Definition: sha512.c:34
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:36
Convenience header that includes libavutil&#39;s core.
static void sha512_transform(uint64_t *state, const uint8_t buffer[128])
Definition: sha512.c:119
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:236
uint64_t state[8]
current hash value
Definition: sha512.c:38
Macro definitions for various function/variable attributes.
#define Sigma1_512(x)
Definition: sha512.c:97
#define AV_WB64(p, v)
Definition: intreadwrite.h:433
The exact code depends on how similar the blocks are and how related they are to the block
uint8_t
#define av_cold
Definition: attributes.h:82
#define f(width, name)
Definition: cbs_vp9.c:255
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
#define Ch(x, y, z)
Definition: sha512.c:93
const int av_sha512_size
Definition: sha512.c:41
struct AVSHA512 * av_sha512_alloc(void)
Allocate an AVSHA512 context.
Definition: sha512.c:43
#define blk0(i)
Definition: sha512.c:101
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
uint8_t digest_len
digest length in 64-bit words
Definition: sha512.c:35
uint8_t bits
Definition: vp3data.h:202
#define av_be2ne64(x)
Definition: bswap.h:94
#define Sigma0_512(x)
Definition: sha512.c:96
#define b
Definition: input.c:41
uint64_t count
number of bytes in buffer
Definition: sha512.c:36
AVFormatContext * ctx
Definition: movenc.c:48
void av_sha512_update(AVSHA512 *ctx, const uint8_t *data, unsigned int len)
Update hash value.
Definition: sha512.c:243
av_cold int av_sha512_init(AVSHA512 *ctx, int bits)
Initialize SHA-2 512 hashing.
Definition: sha512.c:191
#define AV_WB32(p, v)
Definition: intreadwrite.h:419
byte swapping routines
#define R512_16
Public header for SHA-512 implementation.
#define R512_0
int len
void av_sha512_final(AVSHA512 *ctx, uint8_t *digest)
Finish hashing and output digest value.
Definition: sha512.c:273
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later.That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another.Frame references ownership and permissions
GLuint buffer
Definition: opengl_enc.c:101
#define Maj(z, y, x)
Definition: sha512.c:94