1 #include <stdint.h>
2 #include <stdio.h>
3 
4 #include <openssl/evp.h>
5 
6 #define MAX_LENGTH 1024
7 
printhex(const uint8_t * buf,size_t len)8 static void printhex(const uint8_t *buf, size_t len)
9 {
10   for (size_t i = 0; i < len; i++)
11     printf("%02x", buf[i]);
12 }
13 
14 /* This test produces a single hash value which depends on
15  * hashes with all preimage lengths up to max.
16  *
17  * It emits
18  *  H(H(t(0)) || H(t(1)) || ... || H(t(max-1))))
19  * where
20  *  t(n) = (n % 256) ^ n
21  * (informally, t(n) is a n-length octet string of octets with value n mod 256)
22  */
emit_length_test(const char * name,const EVP_MD * h,size_t max)23 static void emit_length_test(const char *name, const EVP_MD *h, size_t max)
24 {
25   EVP_MD_CTX outer, inner;
26   EVP_DigestInit(&outer, h);
27   uint8_t digest[EVP_MAX_MD_SIZE];
28   unsigned int digestlen;
29 
30   for (size_t n = 0; n < max; n++)
31   {
32     EVP_DigestInit(&inner, h);
33     for (size_t i = 0; i < n; i++)
34     {
35       uint8_t byte = n & 0xff;
36       EVP_DigestUpdate(&inner, &byte, 1);
37     }
38     digestlen = sizeof digest;
39     EVP_DigestFinal(&inner, digest, &digestlen);
40 
41     EVP_DigestUpdate(&outer, digest, digestlen);
42   }
43 
44   digestlen = sizeof digest;
45   EVP_DigestFinal(&outer, digest, &digestlen);
46 
47   printf("%s(%zu) = ", name, max);
48   printhex(digest, (size_t) digestlen);
49   printf("\n");
50 }
51 
main(void)52 int main(void)
53 {
54   emit_length_test("SHA1", EVP_sha1(), MAX_LENGTH);
55   emit_length_test("SHA224", EVP_sha224(), MAX_LENGTH);
56   emit_length_test("SHA256", EVP_sha256(), MAX_LENGTH);
57   emit_length_test("SHA384", EVP_sha384(), MAX_LENGTH);
58   emit_length_test("SHA512", EVP_sha512(), MAX_LENGTH);
59   return 0;
60 }
61