1
2#define TEST_NAME "metamorphic"
3#include "cmptest.h"
4
5#define MAXLEN 512
6#define MAX_ITER 1000
7
8static void
9mm_generichash(void)
10{
11    crypto_generichash_state st;
12    unsigned char *h, *h2;
13    unsigned char *k;
14    unsigned char *m;
15    size_t         hlen;
16    size_t         klen;
17    size_t         mlen;
18    size_t         l1, l2;
19    int            i;
20
21    for (i = 0; i < MAX_ITER; i++) {
22        mlen = randombytes_uniform(MAXLEN);
23        m = (unsigned char *) sodium_malloc(mlen);
24        klen = randombytes_uniform(crypto_generichash_KEYBYTES_MAX -
25                                   crypto_generichash_KEYBYTES_MIN + 1U)
26            + crypto_generichash_KEYBYTES_MIN;
27        k = (unsigned char *) sodium_malloc(klen);
28        hlen = randombytes_uniform(crypto_generichash_BYTES_MAX -
29                                   crypto_generichash_BYTES_MIN + 1U)
30            + crypto_generichash_BYTES_MIN;
31        h = (unsigned char *) sodium_malloc(hlen);
32        h2 = (unsigned char *) sodium_malloc(hlen);
33
34        randombytes_buf(k, klen);
35        randombytes_buf(m, mlen);
36
37        crypto_generichash_init(&st, k, klen, hlen);
38        l1 = randombytes_uniform((uint32_t) mlen);
39        l2 = randombytes_uniform((uint32_t) (mlen - l1));
40        crypto_generichash_update(&st, m, l1);
41        crypto_generichash_update(&st, m + l1, l2);
42        crypto_generichash_update(&st, m + l1 + l2, mlen - l1 - l2);
43        crypto_generichash_final(&st, h, hlen);
44
45        crypto_generichash(h2, hlen, m, mlen, k, klen);
46
47        assert(memcmp(h, h2, hlen) == 0);
48
49        sodium_free(h2);
50        sodium_free(h);
51        sodium_free(k);
52        sodium_free(m);
53    }
54}
55
56static void
57mm_onetimeauth(void)
58{
59    crypto_onetimeauth_state st;
60    unsigned char *h, *h2;
61    unsigned char *k;
62    unsigned char *m;
63    size_t         mlen;
64    size_t         l1, l2;
65    int            i;
66
67    for (i = 0; i < MAX_ITER; i++) {
68        mlen = randombytes_uniform(MAXLEN);
69        m = (unsigned char *) sodium_malloc(mlen);
70        k = (unsigned char *) sodium_malloc(crypto_onetimeauth_KEYBYTES);
71        h = (unsigned char *) sodium_malloc(crypto_onetimeauth_BYTES);
72        h2 = (unsigned char *) sodium_malloc(crypto_onetimeauth_BYTES);
73
74        crypto_onetimeauth_keygen(k);
75        randombytes_buf(m, mlen);
76
77        crypto_onetimeauth_init(&st, k);
78        l1 = randombytes_uniform((uint32_t) mlen);
79        l2 = randombytes_uniform((uint32_t) (mlen - l1));
80        crypto_onetimeauth_update(&st, m, l1);
81        crypto_onetimeauth_update(&st, m + l1, l2);
82        crypto_onetimeauth_update(&st, m + l1 + l2, mlen - l1 - l2);
83        crypto_onetimeauth_final(&st, h);
84
85        crypto_onetimeauth(h2, m, mlen, k);
86
87        assert(memcmp(h, h2, crypto_onetimeauth_BYTES) == 0);
88
89        sodium_free(h2);
90        sodium_free(h);
91        sodium_free(k);
92        sodium_free(m);
93    }
94}
95
96static void
97mm_hmacsha256(void)
98{
99    crypto_auth_hmacsha256_state st;
100    unsigned char *h, *h2;
101    unsigned char *k;
102    unsigned char *m;
103    size_t         mlen;
104    size_t         l1, l2;
105    int            i;
106
107    for (i = 0; i < MAX_ITER; i++) {
108        mlen = randombytes_uniform(MAXLEN);
109        m = (unsigned char *) sodium_malloc(mlen);
110        k = (unsigned char *) sodium_malloc(crypto_auth_hmacsha256_KEYBYTES);
111        h = (unsigned char *) sodium_malloc(crypto_auth_hmacsha256_BYTES);
112        h2 = (unsigned char *) sodium_malloc(crypto_auth_hmacsha256_BYTES);
113
114        crypto_auth_hmacsha256_keygen(k);
115        randombytes_buf(m, mlen);
116
117        crypto_auth_hmacsha256_init(&st, k, crypto_auth_hmacsha256_KEYBYTES);
118        l1 = randombytes_uniform((uint32_t) mlen);
119        l2 = randombytes_uniform((uint32_t) (mlen - l1));
120        crypto_auth_hmacsha256_update(&st, m, l1);
121        crypto_auth_hmacsha256_update(&st, m + l1, l2);
122        crypto_auth_hmacsha256_update(&st, m + l1 + l2, mlen - l1 - l2);
123        crypto_auth_hmacsha256_final(&st, h);
124
125        crypto_auth_hmacsha256(h2, m, mlen, k);
126
127        assert(memcmp(h, h2, crypto_auth_hmacsha256_BYTES) == 0);
128
129        sodium_free(h2);
130        sodium_free(h);
131        sodium_free(k);
132        sodium_free(m);
133    }
134}
135
136static void
137mm_hmacsha512(void)
138{
139    crypto_auth_hmacsha512_state st;
140    unsigned char *h, *h2;
141    unsigned char *k;
142    unsigned char *m;
143    size_t         mlen;
144    size_t         l1, l2;
145    int            i;
146
147    for (i = 0; i < MAX_ITER; i++) {
148        mlen = randombytes_uniform(MAXLEN);
149        m = (unsigned char *) sodium_malloc(mlen);
150        k = (unsigned char *) sodium_malloc(crypto_auth_hmacsha512_KEYBYTES);
151        h = (unsigned char *) sodium_malloc(crypto_auth_hmacsha512_BYTES);
152        h2 = (unsigned char *) sodium_malloc(crypto_auth_hmacsha512_BYTES);
153
154        crypto_auth_hmacsha512_keygen(k);
155        randombytes_buf(m, mlen);
156
157        crypto_auth_hmacsha512_init(&st, k, crypto_auth_hmacsha512_KEYBYTES);
158        l1 = randombytes_uniform((uint32_t) mlen);
159        l2 = randombytes_uniform((uint32_t) (mlen - l1));
160        crypto_auth_hmacsha512_update(&st, m, l1);
161        crypto_auth_hmacsha512_update(&st, m + l1, l2);
162        crypto_auth_hmacsha512_update(&st, m + l1 + l2, mlen - l1 - l2);
163        crypto_auth_hmacsha512_final(&st, h);
164
165        crypto_auth_hmacsha512(h2, m, mlen, k);
166
167        assert(memcmp(h, h2, crypto_auth_hmacsha512_BYTES) == 0);
168
169        sodium_free(h2);
170        sodium_free(h);
171        sodium_free(k);
172        sodium_free(m);
173    }
174}
175
176int
177main(void)
178{
179    mm_generichash();
180    mm_onetimeauth();
181    mm_hmacsha256();
182    mm_hmacsha512();
183
184    printf("OK\n");
185
186    return 0;
187}
188