Originally committed as revision 19449 to svn://svn.ffmpeg.org/ffmpeg/trunk
| ... | ... |
@@ -1,6 +1,8 @@ |
| 1 | 1 |
/* |
| 2 | 2 |
* Copyright (C) 2007 Michael Niedermayer <michaelni@gmx.at> |
| 3 |
+ * Copyright (C) 2009 Konstantin Shishkov |
|
| 3 | 4 |
* based on public domain SHA-1 code by Steve Reid <steve@edmweb.com> |
| 5 |
+ * and on BSD-licensed SHA-2 code by Aaron D. Gifford |
|
| 4 | 6 |
* |
| 5 | 7 |
* This file is part of FFmpeg. |
| 6 | 8 |
* |
| ... | ... |
@@ -128,15 +130,155 @@ static void sha1_transform(uint32_t state[5], const uint8_t buffer[64]) |
| 128 | 128 |
state[4] += e; |
| 129 | 129 |
} |
| 130 | 130 |
|
| 131 |
+static const uint32_t K256[64] = {
|
|
| 132 |
+ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, |
|
| 133 |
+ 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, |
|
| 134 |
+ 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, |
|
| 135 |
+ 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, |
|
| 136 |
+ 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, |
|
| 137 |
+ 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, |
|
| 138 |
+ 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, |
|
| 139 |
+ 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, |
|
| 140 |
+ 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, |
|
| 141 |
+ 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, |
|
| 142 |
+ 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, |
|
| 143 |
+ 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, |
|
| 144 |
+ 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, |
|
| 145 |
+ 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, |
|
| 146 |
+ 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, |
|
| 147 |
+ 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 |
|
| 148 |
+}; |
|
| 149 |
+ |
|
| 150 |
+ |
|
| 151 |
+#define Ch(x,y,z) (((x) & ((y) ^ (z))) ^ (z)) |
|
| 152 |
+#define Maj(x,y,z) ((((x) | (y)) & (z)) | ((x) & (y))) |
|
| 153 |
+ |
|
| 154 |
+#define Sigma0_256(x) (rol((x), 30) ^ rol((x), 19) ^ rol((x), 10)) |
|
| 155 |
+#define Sigma1_256(x) (rol((x), 26) ^ rol((x), 21) ^ rol((x), 7)) |
|
| 156 |
+#define sigma0_256(x) (rol((x), 25) ^ rol((x), 14) ^ ((x) >> 3)) |
|
| 157 |
+#define sigma1_256(x) (rol((x), 15) ^ rol((x), 13) ^ ((x) >> 10)) |
|
| 158 |
+ |
|
| 159 |
+#undef blk |
|
| 160 |
+#define blk(i) (block[i] = block[i - 16] + sigma0_256(block[i - 15]) + \ |
|
| 161 |
+ sigma1_256(block[i - 2]) + block[i - 7]) |
|
| 162 |
+ |
|
| 163 |
+#define ROUND256(a,b,c,d,e,f,g,h) \ |
|
| 164 |
+ T1 += (h) + Sigma1_256(e) + Ch((e), (f), (g)) + K256[i]; \ |
|
| 165 |
+ (d) += T1; \ |
|
| 166 |
+ (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ |
|
| 167 |
+ i++ |
|
| 168 |
+ |
|
| 169 |
+#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \ |
|
| 170 |
+ T1 = blk0(i); \ |
|
| 171 |
+ ROUND256(a,b,c,d,e,f,g,h) |
|
| 172 |
+ |
|
| 173 |
+#define ROUND256_16_TO_63(a,b,c,d,e,f,g,h) \ |
|
| 174 |
+ T1 = blk(i); \ |
|
| 175 |
+ ROUND256(a,b,c,d,e,f,g,h) |
|
| 176 |
+ |
|
| 177 |
+static void sha256_transform(uint32_t *state, const uint8_t buffer[64]) |
|
| 178 |
+{
|
|
| 179 |
+ unsigned int i, a, b, c, d, e, f, g, h; |
|
| 180 |
+ uint32_t block[64]; |
|
| 181 |
+ uint32_t T1, T2; |
|
| 182 |
+ |
|
| 183 |
+ a = state[0]; |
|
| 184 |
+ b = state[1]; |
|
| 185 |
+ c = state[2]; |
|
| 186 |
+ d = state[3]; |
|
| 187 |
+ e = state[4]; |
|
| 188 |
+ f = state[5]; |
|
| 189 |
+ g = state[6]; |
|
| 190 |
+ h = state[7]; |
|
| 191 |
+#if CONFIG_SMALL |
|
| 192 |
+ for (i = 0; i < 64; i++) {
|
|
| 193 |
+ if (i < 16) |
|
| 194 |
+ T1 = blk0(i); |
|
| 195 |
+ else |
|
| 196 |
+ T1 = blk(i); |
|
| 197 |
+ T1 += h + Sigma1_256(e) + Ch(e, f, g) + K256[i]; |
|
| 198 |
+ T2 = Sigma0_256(a) + Maj(a, b, c); |
|
| 199 |
+ h = g; |
|
| 200 |
+ g = f; |
|
| 201 |
+ f = e; |
|
| 202 |
+ e = d + T1; |
|
| 203 |
+ d = c; |
|
| 204 |
+ c = b; |
|
| 205 |
+ b = a; |
|
| 206 |
+ a = T1 + T2; |
|
| 207 |
+ } |
|
| 208 |
+#else |
|
| 209 |
+ for (i = 0; i < 16;) {
|
|
| 210 |
+ ROUND256_0_TO_15(a, b, c, d, e, f, g, h); |
|
| 211 |
+ ROUND256_0_TO_15(h, a, b, c, d, e, f, g); |
|
| 212 |
+ ROUND256_0_TO_15(g, h, a, b, c, d, e, f); |
|
| 213 |
+ ROUND256_0_TO_15(f, g, h, a, b, c, d, e); |
|
| 214 |
+ ROUND256_0_TO_15(e, f, g, h, a, b, c, d); |
|
| 215 |
+ ROUND256_0_TO_15(d, e, f, g, h, a, b, c); |
|
| 216 |
+ ROUND256_0_TO_15(c, d, e, f, g, h, a, b); |
|
| 217 |
+ ROUND256_0_TO_15(b, c, d, e, f, g, h, a); |
|
| 218 |
+ } |
|
| 219 |
+ |
|
| 220 |
+ for (; i < 64;) {
|
|
| 221 |
+ ROUND256_16_TO_63(a, b, c, d, e, f, g, h); |
|
| 222 |
+ ROUND256_16_TO_63(h, a, b, c, d, e, f, g); |
|
| 223 |
+ ROUND256_16_TO_63(g, h, a, b, c, d, e, f); |
|
| 224 |
+ ROUND256_16_TO_63(f, g, h, a, b, c, d, e); |
|
| 225 |
+ ROUND256_16_TO_63(e, f, g, h, a, b, c, d); |
|
| 226 |
+ ROUND256_16_TO_63(d, e, f, g, h, a, b, c); |
|
| 227 |
+ ROUND256_16_TO_63(c, d, e, f, g, h, a, b); |
|
| 228 |
+ ROUND256_16_TO_63(b, c, d, e, f, g, h, a); |
|
| 229 |
+ } |
|
| 230 |
+#endif |
|
| 231 |
+ state[0] += a; |
|
| 232 |
+ state[1] += b; |
|
| 233 |
+ state[2] += c; |
|
| 234 |
+ state[3] += d; |
|
| 235 |
+ state[4] += e; |
|
| 236 |
+ state[5] += f; |
|
| 237 |
+ state[6] += g; |
|
| 238 |
+ state[7] += h; |
|
| 239 |
+} |
|
| 240 |
+ |
|
| 241 |
+ |
|
| 131 | 242 |
int av_sha_init(AVSHA* ctx, int bits) |
| 132 | 243 |
{
|
| 244 |
+ ctx->digest_len = bits >> 5; |
|
| 245 |
+ switch (bits) {
|
|
| 246 |
+ case 160: // SHA-1 |
|
| 133 | 247 |
ctx->state[0] = 0x67452301; |
| 134 | 248 |
ctx->state[1] = 0xEFCDAB89; |
| 135 | 249 |
ctx->state[2] = 0x98BADCFE; |
| 136 | 250 |
ctx->state[3] = 0x10325476; |
| 137 | 251 |
ctx->state[4] = 0xC3D2E1F0; |
| 138 | 252 |
ctx->transform = sha1_transform; |
| 139 |
- ctx->count = 0; |
|
| 253 |
+ break; |
|
| 254 |
+ case 224: // SHA-224 |
|
| 255 |
+ ctx->state[0] = 0xC1059ED8; |
|
| 256 |
+ ctx->state[1] = 0x367CD507; |
|
| 257 |
+ ctx->state[2] = 0x3070DD17; |
|
| 258 |
+ ctx->state[3] = 0xF70E5939; |
|
| 259 |
+ ctx->state[4] = 0xFFC00B31; |
|
| 260 |
+ ctx->state[5] = 0x68581511; |
|
| 261 |
+ ctx->state[6] = 0x64F98FA7; |
|
| 262 |
+ ctx->state[7] = 0xBEFA4FA4; |
|
| 263 |
+ ctx->transform = sha256_transform; |
|
| 264 |
+ break; |
|
| 265 |
+ case 256: // SHA-256 |
|
| 266 |
+ ctx->state[0] = 0x6A09E667; |
|
| 267 |
+ ctx->state[1] = 0xBB67AE85; |
|
| 268 |
+ ctx->state[2] = 0x3C6EF372; |
|
| 269 |
+ ctx->state[3] = 0xA54FF53A; |
|
| 270 |
+ ctx->state[4] = 0x510E527F; |
|
| 271 |
+ ctx->state[5] = 0x9B05688C; |
|
| 272 |
+ ctx->state[6] = 0x1F83D9AB; |
|
| 273 |
+ ctx->state[7] = 0x5BE0CD19; |
|
| 274 |
+ ctx->transform = sha256_transform; |
|
| 275 |
+ break; |
|
| 276 |
+ default: |
|
| 277 |
+ return -1; |
|
| 278 |
+ } |
|
| 279 |
+ ctx->count = 0; |
|
| 140 | 280 |
return 0; |
| 141 | 281 |
} |
| 142 | 282 |
|
| ... | ... |
@@ -176,7 +318,7 @@ void av_sha_final(AVSHA* ctx, uint8_t *digest) |
| 176 | 176 |
while ((ctx->count & 63) != 56) |
| 177 | 177 |
av_sha_update(ctx, "", 1); |
| 178 | 178 |
av_sha_update(ctx, (uint8_t *)&finalcount, 8); /* Should cause a transform() */ |
| 179 |
- for (i = 0; i < 5; i++) |
|
| 179 |
+ for (i = 0; i < ctx->digest_len; i++) |
|
| 180 | 180 |
((uint32_t*)digest)[i] = be2me_32(ctx->state[i]); |
| 181 | 181 |
} |
| 182 | 182 |
|
| ... | ... |
@@ -209,12 +351,15 @@ void av_sha1_final(struct AVSHA1* context, uint8_t digest[20]) |
| 209 | 209 |
|
| 210 | 210 |
int main(void) |
| 211 | 211 |
{
|
| 212 |
- int i, k; |
|
| 212 |
+ int i, j, k; |
|
| 213 | 213 |
AVSHA ctx; |
| 214 |
- unsigned char digest[20]; |
|
| 214 |
+ unsigned char digest[32]; |
|
| 215 |
+ const int lengths[3] = { 160, 224, 256 };
|
|
| 215 | 216 |
|
| 217 |
+ for (j = 0; j < 3; j++) {
|
|
| 218 |
+ printf("Testing SHA-%d\n", lengths[j]);
|
|
| 216 | 219 |
for (k = 0; k < 3; k++) {
|
| 217 |
- av_sha_init(&ctx, 160); |
|
| 220 |
+ av_sha_init(&ctx, lengths[j]); |
|
| 218 | 221 |
if (k == 0) |
| 219 | 222 |
av_sha_update(&ctx, "abc", 3); |
| 220 | 223 |
else if (k == 1) |
| ... | ... |
@@ -223,14 +368,31 @@ int main(void) |
| 223 | 223 |
for (i = 0; i < 1000*1000; i++) |
| 224 | 224 |
av_sha_update(&ctx, "a", 1); |
| 225 | 225 |
av_sha_final(&ctx, digest); |
| 226 |
- for (i = 0; i < 20; i++) |
|
| 226 |
+ for (i = 0; i < lengths[j] >> 3; i++) |
|
| 227 | 227 |
printf("%02X", digest[i]);
|
| 228 | 228 |
putchar('\n');
|
| 229 | 229 |
} |
| 230 |
+ switch (j) {
|
|
| 231 |
+ case 0: |
|
| 230 | 232 |
//test vectors (from FIPS PUB 180-1) |
| 231 | 233 |
printf("A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D\n"
|
| 232 | 234 |
"84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1\n" |
| 233 | 235 |
"34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F\n"); |
| 236 |
+ break; |
|
| 237 |
+ case 1: |
|
| 238 |
+ //test vectors (from FIPS PUB 180-2 Appendix A) |
|
| 239 |
+ printf("23097d22 3405d822 8642a477 bda255b3 2aadbce4 bda0b3f7 e36c9da7\n"
|
|
| 240 |
+ "75388b16 512776cc 5dba5da1 fd890150 b0c6455c b4f58b19 52522525\n" |
|
| 241 |
+ "20794655 980c91d8 bbb4c1ea 97618a4b f03f4258 1948b2ee 4ee7ad67\n"); |
|
| 242 |
+ break; |
|
| 243 |
+ case 2: |
|
| 244 |
+ //test vectors (from FIPS PUB 180-2) |
|
| 245 |
+ printf("ba7816bf 8f01cfea 414140de 5dae2223 b00361a3 96177a9c b410ff61 f20015ad\n"
|
|
| 246 |
+ "248d6a61 d20638b8 e5c02693 0c3e6039 a33ce459 64ff2167 f6ecedd4 19db06c1\n" |
|
| 247 |
+ "cdc76e5c 9914fb92 81a1c7e2 84d73e67 f1809a48 a497200e 046d39cc c7112cd0\n"); |
|
| 248 |
+ break; |
|
| 249 |
+ } |
|
| 250 |
+ } |
|
| 234 | 251 |
|
| 235 | 252 |
return 0; |
| 236 | 253 |
} |
| ... | ... |
@@ -28,7 +28,7 @@ extern const int av_sha_size; |
| 28 | 28 |
struct AVSHA; |
| 29 | 29 |
|
| 30 | 30 |
/** |
| 31 |
- * Initializes SHA-1 hashing. |
|
| 31 |
+ * Initializes SHA-1 or SHA-2 hashing. |
|
| 32 | 32 |
* |
| 33 | 33 |
* @param context pointer to the function context (of size av_sha_size) |
| 34 | 34 |
* @param bits number of bits in digest (SHA-1 - 160 bits, SHA-2 224 or 256 bits) |