diff options
author | Daiki Ueno <dueno@redhat.com> | 2020-10-26 13:23:14 +0100 |
---|---|---|
committer | Tomas Mraz <tmraz@fedoraproject.org> | 2020-12-02 16:46:46 +0100 |
commit | c39f43534d4f359bdfee617f70f89b114c9f2cca (patch) | |
tree | 3049586263b57fce903d7b9019ed49c2632303f0 /apps/dgst.c | |
parent | Adapt everything else to the updated OSSL_ENCODER_CTX_new_by_EVP_PKEY() (diff) | |
download | openssl-c39f43534d4f359bdfee617f70f89b114c9f2cca.tar.xz openssl-c39f43534d4f359bdfee617f70f89b114c9f2cca.zip |
openssl dgst: add option to specify output length for XOF
This adds the -xoflen option to control the output length of the XOF
algorithms, such as SHAKE128 and SHAKE256.
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tomas Mraz <tmraz@fedoraproject.org>
(Merged from https://github.com/openssl/openssl/pull/13245)
Diffstat (limited to 'apps/dgst.c')
-rw-r--r-- | apps/dgst.c | 54 |
1 files changed, 43 insertions, 11 deletions
diff --git a/apps/dgst.c b/apps/dgst.c index badcfdf0e2..4adf9cd9b4 100644 --- a/apps/dgst.c +++ b/apps/dgst.c @@ -24,7 +24,7 @@ #undef BUFSIZE #define BUFSIZE 1024*8 -int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout, +int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout, int xoflen, EVP_PKEY *key, unsigned char *sigin, int siglen, const char *sig_name, const char *md_name, const char *file); @@ -40,7 +40,7 @@ typedef enum OPTION_choice { OPT_C, OPT_R, OPT_OUT, OPT_SIGN, OPT_PASSIN, OPT_VERIFY, OPT_PRVERIFY, OPT_SIGNATURE, OPT_KEYFORM, OPT_ENGINE, OPT_ENGINE_IMPL, OPT_HEX, OPT_BINARY, OPT_DEBUG, OPT_FIPS_FINGERPRINT, - OPT_HMAC, OPT_MAC, OPT_SIGOPT, OPT_MACOPT, + OPT_HMAC, OPT_MAC, OPT_SIGOPT, OPT_MACOPT, OPT_XOFLEN, OPT_DIGEST, OPT_R_ENUM, OPT_PROV_ENUM } OPTION_CHOICE; @@ -65,6 +65,7 @@ const OPTIONS dgst_options[] = { {"keyform", OPT_KEYFORM, 'f', "Key file format (ENGINE, other values ignored)"}, {"hex", OPT_HEX, '-', "Print as hex dump"}, {"binary", OPT_BINARY, '-', "Print in binary form"}, + {"xoflen", OPT_XOFLEN, 'p', "Output length for XOF algorithms"}, {"d", OPT_DEBUG, '-', "Print debug info"}, {"debug", OPT_DEBUG, '-', "Print debug info"}, @@ -105,6 +106,7 @@ int dgst_main(int argc, char **argv) OPTION_CHOICE o; int separator = 0, debug = 0, keyform = FORMAT_PEM, siglen = 0; int i, ret = 1, out_bin = -1, want_pub = 0, do_verify = 0; + int xoflen = 0; unsigned char *buf = NULL, *sigbuf = NULL; int engine_impl = 0; struct doall_dgst_digests dec; @@ -180,6 +182,9 @@ int dgst_main(int argc, char **argv) case OPT_BINARY: out_bin = 1; break; + case OPT_XOFLEN: + xoflen = atoi(opt_arg()); + break; case OPT_DEBUG: debug = 1; break; @@ -399,9 +404,20 @@ int dgst_main(int argc, char **argv) if (md != NULL) md_name = EVP_MD_name(md); + if (xoflen > 0) { + if (!(EVP_MD_flags(md) & EVP_MD_FLAG_XOF)) { + BIO_printf(bio_err, "Length can only be specified for XOF\n"); + goto end; + } + if (sigkey != NULL) { + BIO_printf(bio_err, "Signing key cannot be specified for XOF\n"); + goto end; + } + } + if (argc == 0) { BIO_set_fp(in, stdin, BIO_NOCLOSE); - ret = do_fp(out, buf, inp, separator, out_bin, sigkey, sigbuf, + ret = do_fp(out, buf, inp, separator, out_bin, xoflen, sigkey, sigbuf, siglen, NULL, md_name, "stdin"); } else { const char *sig_name = NULL; @@ -417,8 +433,8 @@ int dgst_main(int argc, char **argv) ret++; continue; } else { - r = do_fp(out, buf, inp, separator, out_bin, sigkey, sigbuf, - siglen, sig_name, md_name, argv[i]); + r = do_fp(out, buf, inp, separator, out_bin, xoflen, + sigkey, sigbuf, siglen, sig_name, md_name, argv[i]); } if (r) ret = r; @@ -504,14 +520,14 @@ static const char *newline_escape_filename(const char *file, int * backslash) } -int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout, +int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout, int xoflen, EVP_PKEY *key, unsigned char *sigin, int siglen, const char *sig_name, const char *md_name, const char *file) { size_t len = BUFSIZE; int i, backslash = 0, ret = 1; - unsigned char *sigbuf = NULL; + unsigned char *allocated_buf = NULL; while (BIO_pending(bp) || !BIO_eof(bp)) { i = BIO_read(bp, (char *)buf, BUFSIZE); @@ -552,14 +568,30 @@ int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout, } if (tmplen > BUFSIZE) { len = tmplen; - sigbuf = app_malloc(len, "Signature buffer"); - buf = sigbuf; + allocated_buf = app_malloc(len, "Signature buffer"); + buf = allocated_buf; } if (!EVP_DigestSignFinal(ctx, buf, &len)) { BIO_printf(bio_err, "Error Signing Data\n"); ERR_print_errors(bio_err); goto end; } + } else if (xoflen > 0) { + EVP_MD_CTX *ctx; + + len = xoflen; + if (len > BUFSIZE) { + allocated_buf = app_malloc(len, "Digest buffer"); + buf = allocated_buf; + } + + BIO_get_md_ctx(bp, &ctx); + + if (!EVP_DigestFinalXOF(ctx, buf, len)) { + BIO_printf(bio_err, "Error Digesting Data\n"); + ERR_print_errors(bio_err); + goto end; + } } else { len = BIO_gets(bp, (char *)buf, BUFSIZE); if ((int)len < 0) { @@ -602,8 +634,8 @@ int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout, ret = 0; end: - if (sigbuf != NULL) - OPENSSL_clear_free(sigbuf, len); + if (allocated_buf != NULL) + OPENSSL_clear_free(allocated_buf, len); return ret; } |