libsodium: Needed for Dnscrypto-proxy Release 1.3.0
[tomato.git] / release / src / router / libsodium / src / libsodium / crypto_onetimeauth / poly1305 / onetimeauth_poly1305_try.c
blob72e0191ff40dced62b22f3cc3085a034c824068d
2 #include <stdlib.h>
3 #include <string.h>
4 #include "crypto_hash_sha256.h"
5 #include "crypto_onetimeauth.h"
6 #include "crypto_onetimeauth_poly1305.h"
7 #include "crypto_onetimeauth_poly1305_ref.h"
8 #include "crypto_onetimeauth_poly1305_53.h"
9 #include "utils.h"
11 #define MAXTEST_BYTES 10000
12 #define CHECKSUM_BYTES 4096
14 #define CHECKSUM "e836d5ca58cf673fca2b4910f23f3990"
16 static char checksum[crypto_onetimeauth_BYTES * 2U + 1U];
18 static unsigned char *h, *h_;
19 static unsigned char *m, *m_;
20 static unsigned char *k, *k_;
21 static unsigned char *h2, *h2_;
22 static unsigned char *m2, *m2_;
23 static unsigned char *k2, *k2_;
25 static int
26 allocate(void)
28 h = _sodium_alignedcalloc(&h_, crypto_onetimeauth_BYTES);
29 m = _sodium_alignedcalloc(&m_, MAXTEST_BYTES);
30 k = _sodium_alignedcalloc(&k_, crypto_onetimeauth_KEYBYTES);
31 h2 = _sodium_alignedcalloc(&h2_, crypto_onetimeauth_BYTES);
32 m2 = _sodium_alignedcalloc(&m2_, MAXTEST_BYTES + crypto_onetimeauth_BYTES);
33 k2 = _sodium_alignedcalloc(&k2_, crypto_onetimeauth_KEYBYTES +
34 crypto_onetimeauth_BYTES);
36 return -!(h && m && k && h2 && m2 && k2);
39 static void
40 deallocate(void)
42 free(h_);
43 free(m_);
44 free(k_);
45 free(h2_);
46 free(m2_);
47 free(k2_);
50 static const char *
51 checksum_compute(void)
53 long long i;
54 long long j;
56 for (i = 0;i < CHECKSUM_BYTES;++i) {
57 long long mlen = i;
58 long long klen = crypto_onetimeauth_KEYBYTES;
59 long long hlen = crypto_onetimeauth_BYTES;
61 for (j = -16;j < 0;++j) h[j] = rand();
62 for (j = -16;j < 0;++j) k[j] = rand();
63 for (j = -16;j < 0;++j) m[j] = rand();
64 for (j = hlen;j < hlen + 16;++j) h[j] = rand();
65 for (j = klen;j < klen + 16;++j) k[j] = rand();
66 for (j = mlen;j < mlen + 16;++j) m[j] = rand();
67 for (j = -16;j < hlen + 16;++j) h2[j] = h[j];
68 for (j = -16;j < klen + 16;++j) k2[j] = k[j];
69 for (j = -16;j < mlen + 16;++j) m2[j] = m[j];
71 if (crypto_onetimeauth(h,m,mlen,k) != 0) return "crypto_onetimeauth returns nonzero";
73 for (j = -16;j < klen + 16;++j) if (k[j] != k2[j]) return "crypto_onetimeauth overwrites k";
74 for (j = -16;j < mlen + 16;++j) if (m[j] != m2[j]) return "crypto_onetimeauth overwrites m";
75 for (j = -16;j < 0;++j) if (h[j] != h2[j]) return "crypto_onetimeauth writes before output";
76 for (j = hlen;j < hlen + 16;++j) if (h[j] != h2[j]) return "crypto_onetimeauth writes after output";
78 for (j = -16;j < 0;++j) h[j] = rand();
79 for (j = -16;j < 0;++j) k[j] = rand();
80 for (j = -16;j < 0;++j) m[j] = rand();
81 for (j = hlen;j < hlen + 16;++j) h[j] = rand();
82 for (j = klen;j < klen + 16;++j) k[j] = rand();
83 for (j = mlen;j < mlen + 16;++j) m[j] = rand();
84 for (j = -16;j < hlen + 16;++j) h2[j] = h[j];
85 for (j = -16;j < klen + 16;++j) k2[j] = k[j];
86 for (j = -16;j < mlen + 16;++j) m2[j] = m[j];
88 if (crypto_onetimeauth(m2,m2,mlen,k) != 0) return "crypto_onetimeauth returns nonzero";
89 for (j = 0;j < hlen;++j) if (m2[j] != h[j]) return "crypto_onetimeauth does not handle m overlap";
90 for (j = 0;j < hlen;++j) m2[j] = m[j];
91 if (crypto_onetimeauth(k2,m2,mlen,k2) != 0) return "crypto_onetimeauth returns nonzero";
92 for (j = 0;j < hlen;++j) if (k2[j] != h[j]) return "crypto_onetimeauth does not handle k overlap";
93 for (j = 0;j < hlen;++j) k2[j] = k[j];
95 if (crypto_onetimeauth_verify(h,m,mlen,k) != 0) return "crypto_onetimeauth_verify returns nonzero";
97 for (j = -16;j < hlen + 16;++j) if (h[j] != h2[j]) return "crypto_onetimeauth overwrites h";
98 for (j = -16;j < klen + 16;++j) if (k[j] != k2[j]) return "crypto_onetimeauth overwrites k";
99 for (j = -16;j < mlen + 16;++j) if (m[j] != m2[j]) return "crypto_onetimeauth overwrites m";
101 crypto_hash_sha256(h2,h,hlen);
102 for (j = 0;j < klen;++j) k[j] ^= h2[j % 32];
103 if (crypto_onetimeauth(h,m,mlen,k) != 0) return "crypto_onetimeauth returns nonzero";
104 if (crypto_onetimeauth_verify(h,m,mlen,k) != 0) return "crypto_onetimeauth_verify returns nonzero";
106 crypto_hash_sha256(h2,h,hlen);
107 for (j = 0;j < mlen;++j) m[j] ^= h2[j % 32];
108 m[mlen] = h2[0];
110 if (crypto_onetimeauth(h,m,CHECKSUM_BYTES,k) != 0) return "crypto_onetimeauth returns nonzero";
111 if (crypto_onetimeauth_verify(h,m,CHECKSUM_BYTES,k) != 0) return "crypto_onetimeauth_verify returns nonzero";
113 for (i = 0;i < crypto_onetimeauth_BYTES;++i) {
114 checksum[2 * i] = "0123456789abcdef"[15 & (h[i] >> 4)];
115 checksum[2 * i + 1] = "0123456789abcdef"[15 & h[i]];
117 checksum[2 * i] = 0;
119 return NULL;
122 crypto_onetimeauth_poly1305_implementation *
123 crypto_onetimeauth_pick_best_implementation(void)
125 crypto_onetimeauth_poly1305_implementation *implementations[] = {
126 #ifdef HAVE_FENV_H
127 &crypto_onetimeauth_poly1305_53_implementation,
128 #endif
129 &crypto_onetimeauth_poly1305_ref_implementation,
130 NULL
132 const char *err;
133 size_t i = (size_t) 0U;
135 do {
136 if (crypto_onetimeauth_poly1305_set_implementation
137 (implementations[i]) != 0) {
138 continue;
140 if (allocate() != 0) {
141 return NULL;
143 err = checksum_compute();
144 deallocate();
145 if (err == NULL && strcmp(checksum, CHECKSUM) == 0) {
146 break;
148 } while (implementations[++i] != NULL);
150 return implementations[i];