1*657b055cStb /* $OpenBSD: poly1305test.c,v 1.3 2018/07/17 17:06:49 tb Exp $ */
24bc16da3Sjsing /*
34bc16da3Sjsing * Public Domain poly1305 from Andrew Moon
44bc16da3Sjsing * Based on poly1305-donna.c from:
54bc16da3Sjsing * https://github.com/floodyberry/poly1305-donna
64bc16da3Sjsing */
74bc16da3Sjsing
84bc16da3Sjsing #include <stdio.h>
94bc16da3Sjsing
104bc16da3Sjsing #include <openssl/poly1305.h>
114bc16da3Sjsing
124bc16da3Sjsing void poly1305_auth(unsigned char mac[16], const unsigned char *m, size_t bytes,
134bc16da3Sjsing const unsigned char key[32]);
144bc16da3Sjsing
154bc16da3Sjsing int poly1305_verify(const unsigned char mac1[16], const unsigned char mac2[16]);
164bc16da3Sjsing int poly1305_power_on_self_test(void);
174bc16da3Sjsing
184bc16da3Sjsing void
poly1305_auth(unsigned char mac[16],const unsigned char * m,size_t bytes,const unsigned char key[32])194bc16da3Sjsing poly1305_auth(unsigned char mac[16], const unsigned char *m, size_t bytes,
204bc16da3Sjsing const unsigned char key[32]) {
214bc16da3Sjsing poly1305_context ctx;
224bc16da3Sjsing CRYPTO_poly1305_init(&ctx, key);
234bc16da3Sjsing CRYPTO_poly1305_update(&ctx, m, bytes);
244bc16da3Sjsing CRYPTO_poly1305_finish(&ctx, mac);
254bc16da3Sjsing }
264bc16da3Sjsing
274bc16da3Sjsing int
poly1305_verify(const unsigned char mac1[16],const unsigned char mac2[16])285ffa517cSjsing poly1305_verify(const unsigned char mac1[16], const unsigned char mac2[16])
295ffa517cSjsing {
304bc16da3Sjsing size_t i;
314bc16da3Sjsing unsigned int dif = 0;
324bc16da3Sjsing for (i = 0; i < 16; i++)
334bc16da3Sjsing dif |= (mac1[i] ^ mac2[i]);
344bc16da3Sjsing dif = (dif - 1) >> ((sizeof(unsigned int) * 8) - 1);
354bc16da3Sjsing return (dif & 1);
364bc16da3Sjsing }
374bc16da3Sjsing
384bc16da3Sjsing /* test a few basic operations */
394bc16da3Sjsing int
poly1305_power_on_self_test(void)405ffa517cSjsing poly1305_power_on_self_test(void)
415ffa517cSjsing {
424bc16da3Sjsing /* example from nacl */
434bc16da3Sjsing static const unsigned char nacl_key[32] = {
444bc16da3Sjsing 0xee, 0xa6, 0xa7, 0x25, 0x1c, 0x1e, 0x72, 0x91,
454bc16da3Sjsing 0x6d, 0x11, 0xc2, 0xcb, 0x21, 0x4d, 0x3c, 0x25,
464bc16da3Sjsing 0x25, 0x39, 0x12, 0x1d, 0x8e, 0x23, 0x4e, 0x65,
474bc16da3Sjsing 0x2d, 0x65, 0x1f, 0xa4, 0xc8, 0xcf, 0xf8, 0x80,
484bc16da3Sjsing };
494bc16da3Sjsing
504bc16da3Sjsing static const unsigned char nacl_msg[131] = {
514bc16da3Sjsing 0x8e, 0x99, 0x3b, 0x9f, 0x48, 0x68, 0x12, 0x73,
524bc16da3Sjsing 0xc2, 0x96, 0x50, 0xba, 0x32, 0xfc, 0x76, 0xce,
534bc16da3Sjsing 0x48, 0x33, 0x2e, 0xa7, 0x16, 0x4d, 0x96, 0xa4,
544bc16da3Sjsing 0x47, 0x6f, 0xb8, 0xc5, 0x31, 0xa1, 0x18, 0x6a,
554bc16da3Sjsing 0xc0, 0xdf, 0xc1, 0x7c, 0x98, 0xdc, 0xe8, 0x7b,
564bc16da3Sjsing 0x4d, 0xa7, 0xf0, 0x11, 0xec, 0x48, 0xc9, 0x72,
574bc16da3Sjsing 0x71, 0xd2, 0xc2, 0x0f, 0x9b, 0x92, 0x8f, 0xe2,
584bc16da3Sjsing 0x27, 0x0d, 0x6f, 0xb8, 0x63, 0xd5, 0x17, 0x38,
594bc16da3Sjsing 0xb4, 0x8e, 0xee, 0xe3, 0x14, 0xa7, 0xcc, 0x8a,
604bc16da3Sjsing 0xb9, 0x32, 0x16, 0x45, 0x48, 0xe5, 0x26, 0xae,
614bc16da3Sjsing 0x90, 0x22, 0x43, 0x68, 0x51, 0x7a, 0xcf, 0xea,
624bc16da3Sjsing 0xbd, 0x6b, 0xb3, 0x73, 0x2b, 0xc0, 0xe9, 0xda,
634bc16da3Sjsing 0x99, 0x83, 0x2b, 0x61, 0xca, 0x01, 0xb6, 0xde,
644bc16da3Sjsing 0x56, 0x24, 0x4a, 0x9e, 0x88, 0xd5, 0xf9, 0xb3,
654bc16da3Sjsing 0x79, 0x73, 0xf6, 0x22, 0xa4, 0x3d, 0x14, 0xa6,
664bc16da3Sjsing 0x59, 0x9b, 0x1f, 0x65, 0x4c, 0xb4, 0x5a, 0x74,
674bc16da3Sjsing 0xe3, 0x55, 0xa5
684bc16da3Sjsing };
694bc16da3Sjsing
704bc16da3Sjsing static const unsigned char nacl_mac[16] = {
714bc16da3Sjsing 0xf3, 0xff, 0xc7, 0x70, 0x3f, 0x94, 0x00, 0xe5,
724bc16da3Sjsing 0x2a, 0x7d, 0xfb, 0x4b, 0x3d, 0x33, 0x05, 0xd9
734bc16da3Sjsing };
744bc16da3Sjsing
754bc16da3Sjsing /* generates a final value of (2^130 - 2) == 3 */
764bc16da3Sjsing static const unsigned char wrap_key[32] = {
774bc16da3Sjsing 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
784bc16da3Sjsing 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
794bc16da3Sjsing 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
804bc16da3Sjsing 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
814bc16da3Sjsing };
824bc16da3Sjsing
834bc16da3Sjsing static const unsigned char wrap_msg[16] = {
844bc16da3Sjsing 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
854bc16da3Sjsing 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
864bc16da3Sjsing };
874bc16da3Sjsing
884bc16da3Sjsing static const unsigned char wrap_mac[16] = {
894bc16da3Sjsing 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
904bc16da3Sjsing 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
914bc16da3Sjsing };
924bc16da3Sjsing
934bc16da3Sjsing /*
944bc16da3Sjsing mac of the macs of messages of length 0 to 256, where the key and messages
954bc16da3Sjsing have all their values set to the length
964bc16da3Sjsing */
974bc16da3Sjsing static const unsigned char total_key[32] = {
984bc16da3Sjsing 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
994bc16da3Sjsing 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9,
1004bc16da3Sjsing 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1014bc16da3Sjsing 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
1024bc16da3Sjsing };
1034bc16da3Sjsing
1044bc16da3Sjsing static const unsigned char total_mac[16] = {
1054bc16da3Sjsing 0x64, 0xaf, 0xe2, 0xe8, 0xd6, 0xad, 0x7b, 0xbd,
1064bc16da3Sjsing 0xd2, 0x87, 0xf9, 0x7c, 0x44, 0x62, 0x3d, 0x39
1074bc16da3Sjsing };
1084bc16da3Sjsing
1094bc16da3Sjsing poly1305_context ctx;
1104bc16da3Sjsing poly1305_context total_ctx;
1114bc16da3Sjsing unsigned char all_key[32];
1124bc16da3Sjsing unsigned char all_msg[256];
1134bc16da3Sjsing unsigned char mac[16];
1144bc16da3Sjsing size_t i, j;
1154bc16da3Sjsing int result = 1;
1164bc16da3Sjsing
1174bc16da3Sjsing for (i = 0; i < sizeof(mac); i++)
1184bc16da3Sjsing mac[i] = 0;
1194bc16da3Sjsing poly1305_auth(mac, nacl_msg, sizeof(nacl_msg), nacl_key);
1204bc16da3Sjsing result &= poly1305_verify(nacl_mac, mac);
1214bc16da3Sjsing
1224bc16da3Sjsing for (i = 0; i < sizeof(mac); i++)
1234bc16da3Sjsing mac[i] = 0;
1244bc16da3Sjsing CRYPTO_poly1305_init(&ctx, nacl_key);
1254bc16da3Sjsing CRYPTO_poly1305_update(&ctx, nacl_msg + 0, 32);
1264bc16da3Sjsing CRYPTO_poly1305_update(&ctx, nacl_msg + 32, 64);
1274bc16da3Sjsing CRYPTO_poly1305_update(&ctx, nacl_msg + 96, 16);
1284bc16da3Sjsing CRYPTO_poly1305_update(&ctx, nacl_msg + 112, 8);
1294bc16da3Sjsing CRYPTO_poly1305_update(&ctx, nacl_msg + 120, 4);
1304bc16da3Sjsing CRYPTO_poly1305_update(&ctx, nacl_msg + 124, 2);
1314bc16da3Sjsing CRYPTO_poly1305_update(&ctx, nacl_msg + 126, 1);
1324bc16da3Sjsing CRYPTO_poly1305_update(&ctx, nacl_msg + 127, 1);
1334bc16da3Sjsing CRYPTO_poly1305_update(&ctx, nacl_msg + 128, 1);
1344bc16da3Sjsing CRYPTO_poly1305_update(&ctx, nacl_msg + 129, 1);
1354bc16da3Sjsing CRYPTO_poly1305_update(&ctx, nacl_msg + 130, 1);
1364bc16da3Sjsing CRYPTO_poly1305_finish(&ctx, mac);
1374bc16da3Sjsing result &= poly1305_verify(nacl_mac, mac);
1384bc16da3Sjsing
1394bc16da3Sjsing for (i = 0; i < sizeof(mac); i++)
1404bc16da3Sjsing mac[i] = 0;
1414bc16da3Sjsing poly1305_auth(mac, wrap_msg, sizeof(wrap_msg), wrap_key);
1424bc16da3Sjsing result &= poly1305_verify(wrap_mac, mac);
1434bc16da3Sjsing
1444bc16da3Sjsing CRYPTO_poly1305_init(&total_ctx, total_key);
1454bc16da3Sjsing for (i = 0; i < 256; i++) {
1464bc16da3Sjsing /* set key and message to 'i,i,i..' */
1474bc16da3Sjsing for (j = 0; j < sizeof(all_key); j++)
1484bc16da3Sjsing all_key[j] = i;
1494bc16da3Sjsing for (j = 0; j < i; j++)
1504bc16da3Sjsing all_msg[j] = i;
1514bc16da3Sjsing poly1305_auth(mac, all_msg, i, all_key);
1524bc16da3Sjsing CRYPTO_poly1305_update(&total_ctx, mac, 16);
1534bc16da3Sjsing }
1544bc16da3Sjsing CRYPTO_poly1305_finish(&total_ctx, mac);
1554bc16da3Sjsing result &= poly1305_verify(total_mac, mac);
1564bc16da3Sjsing
1574bc16da3Sjsing return result;
1584bc16da3Sjsing }
1594bc16da3Sjsing
1604bc16da3Sjsing int
main(int argc,char ** argv)1614bc16da3Sjsing main(int argc, char **argv)
1624bc16da3Sjsing {
1634bc16da3Sjsing if (!poly1305_power_on_self_test()) {
1644bc16da3Sjsing fprintf(stderr, "One or more self tests failed!\n");
1654bc16da3Sjsing return 1;
1664bc16da3Sjsing }
1674bc16da3Sjsing
1684bc16da3Sjsing return 0;
1694bc16da3Sjsing }
170