1 /* 2 * Copyright 2017 Donald Stufft and individual contributors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 * 16 * Test vector generator/checker for libsodium's box_seal APIs 17 * to build in a unix-like environment, use a command line like 18 * $ cc sealbox_test_vectors.c -I${IPATH} -L${LPATH} -lsodium -o sealbox_test_vectors 19 * with IPATH and LPATH defined to respectively point to libsodium's include path 20 * and to the directory containing the link library libsodium.a or libsodium.o 21 * 22 */ 23 #include <stdio.h> 24 #include <string.h> 25 #include <sodium.h> 26 27 int checkone (char *hxsecret, char *hxpub, size_t ptlen, char *hxplaintext, 28 size_t crlen, char *hxencrypted) { 29 30 int pklen = crypto_box_PUBLICKEYBYTES; 31 int sklen = crypto_box_SECRETKEYBYTES; 32 33 char *skr = sodium_malloc (sklen); 34 char *pub = sodium_malloc (pklen); 35 char *txt = sodium_malloc (ptlen); 36 char *crpt = sodium_malloc (crlen); 37 char *outp = sodium_malloc (ptlen); 38 39 int rs = sodium_hex2bin (skr, sklen, hxsecret, 2 * sklen, 40 NULL, NULL, NULL); 41 rs |= sodium_hex2bin (pub, pklen, hxpub, 2 * pklen, NULL, NULL, NULL); 42 rs |= sodium_hex2bin (txt, ptlen, hxplaintext, strlen (hxplaintext), 43 NULL, NULL, NULL); 44 rs |= sodium_hex2bin (crpt, crlen, hxencrypted, strlen (hxencrypted), 45 NULL, NULL, NULL); 46 47 if (rs == 0) 48 rs = crypto_box_seal_open (outp, crpt, crlen, pub, skr); 49 if (rs == 0) 50 rs = sodium_memcmp (outp, txt, ptlen); 51 52 sodium_free (crpt); 53 sodium_free (txt); 54 sodium_free (skr); 55 sodium_free (pub); 56 57 return rs; 58 } 59 60 void gentestline (int minmsglen, int maxmsglen) { 61 62 int pklen = crypto_box_PUBLICKEYBYTES; 63 int sklen = crypto_box_SECRETKEYBYTES; 64 size_t txtlen = minmsglen + randombytes_uniform (maxmsglen - minmsglen + 1); 65 size_t encrlen = txtlen + crypto_box_SEALBYTES; 66 67 char *skr = sodium_malloc (sklen); 68 char *pub = sodium_malloc (pklen); 69 char *txt = sodium_malloc (txtlen); 70 char *crpt = sodium_malloc (encrlen); 71 72 crypto_box_keypair (pub, skr); 73 randombytes_buf (txt, txtlen); 74 75 crypto_box_seal (crpt, txt, txtlen, pub); 76 77 char *hskr = sodium_malloc (sklen * 2 + 1); 78 char *hpub = sodium_malloc (pklen * 2 + 1); 79 char *htxt = sodium_malloc (txtlen * 2 + 1); 80 char *hkrp = sodium_malloc (encrlen * 2 + 1); 81 82 sodium_bin2hex (hskr, sklen * 2 + 1, skr, sklen); 83 sodium_bin2hex (hpub, pklen * 2 + 1, pub, pklen); 84 sodium_bin2hex (htxt, txtlen * 2 + 1, txt, txtlen); 85 sodium_bin2hex (hkrp, encrlen * 2 + 1, crpt, encrlen); 86 87 printf ("%s\t%s\t%zu:%s\t%zu:%s\n", hskr, hpub, txtlen, htxt, encrlen, hkrp); 88 } 89 90 int main (int argc, char **argv) { 91 /* 92 * If called without any argument, the resulting executable will 93 * read and hex decode the secret and public part of the receiver key, 94 * the original plaintext and the ciphertext, and then 95 * check if the message resulting from decrypting ciphertext with 96 * the secret key is equal to the given plaintext 97 * 98 * If called with a sequence of integer arguments, sealbox_test_vectors 99 * will generate the requested number of reference lines, encrypting 100 * random messages. 101 * 102 */ 103 if (sodium_init () == -1) { 104 exit (1); 105 } 106 107 if (argc == 1) { 108 size_t lsz = 0; 109 char *line = NULL; 110 ssize_t lln = 0; 111 int res; 112 char hxsecret[2 * crypto_box_SECRETKEYBYTES + 1]; 113 char hxpub[2 * crypto_box_PUBLICKEYBYTES + 1]; 114 char hxplaintext[2048 + 1]; 115 char hxencrypted[2048 + 2 * crypto_box_SEALBYTES + 1]; 116 char cmpplaintext[5 + 2048 + 1]; 117 char cmpencrypted[5 + 2048 + 2 * crypto_box_SEALBYTES + 1]; 118 size_t ptlen = 0; 119 size_t crlen = 0; 120 121 while (lln = getline (&line, &lsz, stdin) > 0) { 122 if (lln > 0) { 123 if (strncmp (line, "#", 1) == 0 || 124 strncmp (line, "\n", 1) == 0 || 125 strncmp (line, "\r", 1) == 0) 126 continue; 127 128 sscanf (line, "%s%s%s%s", 129 hxsecret, hxpub, cmpplaintext, cmpencrypted); 130 sscanf (cmpplaintext, "%zu:%s", 131 &ptlen, hxplaintext); 132 sscanf (cmpencrypted, "%zu:%s", 133 &crlen, hxencrypted); 134 if (ptlen == 0) 135 memset(hxplaintext, 0, sizeof(hxplaintext)); 136 if (crlen == 0) 137 memset(hxencrypted, 0, sizeof(hxencrypted)); 138 res = checkone (hxsecret, hxpub, ptlen, hxplaintext, crlen, hxencrypted); 139 char *rsstr = (res == 0) ? "OK" : "FAIL"; 140 printf ("%s\t%s\t%zu:%s\t%zu:%s\t%s\n", 141 hxsecret, hxpub, ptlen, hxplaintext, crlen, hxencrypted, rsstr); 142 } 143 free (line); 144 line = NULL; 145 } 146 } else { 147 int nlines = atoi (argv[1]); 148 int minmsgl = 128; 149 int maxmsgl = 128; 150 if (argc == 3) { 151 minmsgl = atoi (argv[2]); 152 maxmsgl = atoi (argv[2]) * 2; 153 } else if (argc == 4) { 154 minmsgl = atoi (argv[2]); 155 maxmsgl = atoi (argv[3]); 156 } 157 for (int i = 0; i < nlines; i++) { 158 gentestline (minmsgl, maxmsgl); 159 } 160 } 161 } 162