diff --git a/lilcrypto.h b/lilcrypto.h index f599c36..3e2fdb2 100644 --- a/lilcrypto.h +++ b/lilcrypto.h @@ -16,6 +16,7 @@ #include #include +#include /* @@ -110,4 +111,5 @@ const struct lc_aead_impl *lc_aead_impl_chacha20_poly1305(void); * Utilities. */ +int lc_hexdump_fp(FILE *, const void *, size_t); void lc_scrub(void *, size_t); diff --git a/util.c b/util.c index 9836368..5e38290 100644 --- a/util.c +++ b/util.c @@ -14,11 +14,107 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include #include #include "lilcrypto.h" +#define HEXDUMP_BUFSZ 128 + + +static size_t +hexdump_line(char *buf, const uint8_t *blob, size_t len, size_t off, int pad) +{ + /* + * Format is + * - 16-char hex offset (at most) + * - 2 spaces + * - 2-char hex byte and a space (16 times) + * - 2 spaces + * - 2 pipe chars + 16 renders of the blobs + * + * That accounts for, at most, 16 + 2 + 16 * 3 + 2 + 18. Adding an + * extra byte for the NUL ending byte, that amounts for 87. + * + * Callers MUST provide a buffer at least HEXDUMP_BUFSZ long in buf0. + */ + + char *bufp; + size_t i, buflen; + int w; + + bufp = buf; + buflen = HEXDUMP_BUFSZ; + + if (len == 0) + (void)snprintf(bufp, buflen, "%0*zx\n", pad, off); + else { + w = snprintf(bufp, buflen, "%0*zx ", pad, off); + bufp += w; + buflen -= w; + for (i = 0; i < len && i < 8; i++) { + w = snprintf(bufp, buflen, "%02x ", blob[i]); + bufp += w; + buflen -= w; + } + if (i < 8) { + memset(bufp, ' ', 3 * (16 - i)); + bufp += 3 * (16 - i); + buflen -= 3 * (16 - i); + } + for (; i < len && i < 16; i++) { + w = snprintf(bufp, buflen, " %02x", blob[i]); + bufp += w; + buflen -= w; + } + if (i < 16) { + memset(bufp, ' ', 3 * (16 - i)); + bufp += 3 * (16 - i); + buflen -= 3 * (16 - i); + } + w = snprintf(bufp, buflen, " |"); + bufp += w; + buflen -= w; + for (i = 0; i < len && i < 16; i++) { + w = snprintf(bufp, buflen, "%c", + isprint(blob[i]) ? blob[i] : '.'); + bufp += w; + buflen -= w; + } + (void)snprintf(bufp, buflen, "|\n"); + } + + return len < 16 ? len : 16; +} + +int +lc_hexdump_fp(FILE *fp, const void *blob, size_t len) +{ + const uint8_t *p = blob; + char buf[HEXDUMP_BUFSZ]; + size_t l, off; + int pad; + + for (pad = 1; len > (1 << (8 * pad)); pad++) + continue; + pad *= 2; + + off = 0; + while (len > 0) { + l = hexdump_line(buf, p, len, off, pad); + if (fputs(buf, fp) == EOF) + return 0; + off += l; + len -= l; + } + (void)hexdump_line(buf, p, len, off, pad); + if (fputs(buf, fp) == EOF) + return 0; + + return 1; +} + void lc_scrub(void *b, size_t len) { diff --git a/wycheproof_aead.c b/wycheproof_aead.c index 4955696..2d6f3b6 100644 --- a/wycheproof_aead.c +++ b/wycheproof_aead.c @@ -60,58 +60,6 @@ hexparse(const char *s, uint8_t *out, size_t *outlen) return 1; } -static void -hexdump(FILE *fp, const uint8_t *blob, size_t len) -{ - size_t i, off; - int pad; - - for (i = 0; len > (1 << (8 * i)); i++) - ; - pad = (i + 1) * 2; - - off = 0; - while (len >= 16) { - fprintf(fp, "%0*zx\t", pad, off); - - for (i = 0; i < 8; i++) - fprintf(fp, "%02x ", blob[i]); - for (; i < 16; i++) - fprintf(fp, " %02x", blob[i]); - - fprintf(fp, "\t|"); - for (i = 0; i < 16; i++) - fprintf(fp, "%c", isprint(blob[i]) ? blob[i] : '.'); - fprintf(fp, "|\n"); - - blob += 16; - off += 16; - len -= 16; - } - - if (len == 0) - goto out; - - fprintf(fp, "%0*zx\t", pad, off); - for (i = 0; i < len && i < 8; i++) - fprintf(fp, "%02x ", blob[i]); - for (; i < 8; i++) - fprintf(fp, " "); - for (; i < len && i < 16; i++) - fprintf(fp, " %02x", blob[i]); - for (; i < 16; i++) - fprintf(fp, " "); - - fprintf(fp, "\t|"); - for (i = 0; i < len; i++) - fprintf(fp, "%c", isprint(blob[i]) ? blob[i] : '.'); - fprintf(fp, "|\n"); - - out: - fprintf(fp, "%0*zx\n", pad, off + len); - fflush(fp); -} - struct kwimpl { const char *kw; const struct lc_aead_impl *(*impl)(void); @@ -305,11 +253,11 @@ main(int argc, char *argv[]) if (verbose) { fprintf(stderr, "ct (%zu, %zu)\n", ctlen, encoutlen - LC_POLY1305_TAGLEN); - hexdump(stderr, msg, msglen); + lc_hexdump_fp(stderr, msg, msglen); fprintf(stderr, "\n"); - hexdump(stderr, ct, ctlen); + lc_hexdump_fp(stderr, ct, ctlen); fprintf(stderr, "\n"); - hexdump(stderr, encout, + lc_hexdump_fp(stderr, encout, encoutlen - LC_POLY1305_TAGLEN); fprintf(stderr, "\n"); } @@ -321,9 +269,9 @@ main(int argc, char *argv[]) if (verbose) { fprintf(stderr, "tag (%zu, %zu)\n", taglenarg, (size_t)LC_POLY1305_TAGLEN); - hexdump(stderr, tag, taglen); + lc_hexdump_fp(stderr, tag, taglen); fprintf(stderr, "\n"); - hexdump(stderr, encout + ctlen, LC_POLY1305_TAGLEN); + lc_hexdump_fp(stderr, encout + ctlen, LC_POLY1305_TAGLEN); fprintf(stderr, "\n"); } puts("invalid"); @@ -355,11 +303,11 @@ main(int argc, char *argv[]) if (msglen != decoutlen || lc_ct_cmp(decout, msg, msglen) != 0) { if (verbose) { fprintf(stderr, "ct (%zu, %zu)\n", msglen, decoutlen); - hexdump(stderr, msg, msglen); + lc_hexdump_fp(stderr, msg, msglen); fprintf(stderr, "\n"); - hexdump(stderr, ct, ctlen); + lc_hexdump_fp(stderr, ct, ctlen); fprintf(stderr, "\n"); - hexdump(stderr, decout, decoutlen); + lc_hexdump_fp(stderr, decout, decoutlen); fprintf(stderr, "\n"); } puts("invalid");