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"
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_
;
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
);
51 checksum_compute(void)
56 for (i
= 0;i
< CHECKSUM_BYTES
;++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];
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
]];
122 crypto_onetimeauth_poly1305_implementation
*
123 crypto_onetimeauth_pick_best_implementation(void)
125 crypto_onetimeauth_poly1305_implementation
*implementations
[] = {
127 &crypto_onetimeauth_poly1305_53_implementation
,
129 &crypto_onetimeauth_poly1305_ref_implementation
,
133 size_t i
= (size_t) 0U;
136 if (crypto_onetimeauth_poly1305_set_implementation
137 (implementations
[i
]) != 0) {
140 if (allocate() != 0) {
143 err
= checksum_compute();
145 if (err
== NULL
&& strcmp(checksum
, CHECKSUM
) == 0) {
148 } while (implementations
[++i
] != NULL
);
150 return implementations
[i
];