2 * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
4 * Licensed under the OpenSSL license (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
14 #include <openssl/bio.h>
15 #include <openssl/err.h>
16 #include <openssl/evp.h>
17 #include <openssl/kdf.h>
19 typedef enum OPTION_choice {
20 OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
21 OPT_KDFOPT, OPT_BIN, OPT_KEYLEN, OPT_OUT
24 const OPTIONS kdf_options[] = {
25 {OPT_HELP_STR, 1, '-', "Usage: %s [options] kdf_name\n"},
26 {OPT_HELP_STR, 1, '-', "kdf_name\t KDF algorithm.\n"},
27 {"help", OPT_HELP, '-', "Display this summary"},
28 {"kdfopt", OPT_KDFOPT, 's', "KDF algorithm control parameters in n:v form. "
29 "See 'Supported Controls' in the EVP_KDF_ docs"},
30 {"keylen", OPT_KEYLEN, 's', "The size of the output derived key"},
31 {"out", OPT_OUT, '>', "Output to filename rather than stdout"},
32 {"binary", OPT_BIN, '-', "Output in binary format (Default is hexadecimal "
37 static int kdf_ctrl_string(EVP_KDF_CTX *ctx, const char *value)
40 char *stmp, *vtmp = NULL;
42 stmp = OPENSSL_strdup(value);
45 vtmp = strchr(stmp, ':');
50 rv = EVP_KDF_ctrl_str(ctx, stmp, vtmp);
55 int kdf_main(int argc, char **argv)
57 int ret = 1, i, id, out_bin = 0;
59 STACK_OF(OPENSSL_STRING) *opts = NULL;
60 char *prog, *hexout = NULL;
61 const char *outfile = NULL;
62 unsigned char *dkm_bytes = NULL;
65 EVP_KDF_CTX *ctx = NULL;
67 prog = opt_init(argc, argv, kdf_options);
68 while ((o = opt_next()) != OPT_EOF) {
72 BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
75 opt_help(kdf_options);
82 dkm_len = (size_t)atoi(opt_arg());
89 opts = sk_OPENSSL_STRING_new_null();
90 if (opts == NULL || !sk_OPENSSL_STRING_push(opts, opt_arg()))
95 argc = opt_num_rest();
99 BIO_printf(bio_err, "Invalid number of extra arguments\n");
103 id = OBJ_sn2nid(argv[0]);
104 if (id == NID_undef) {
105 BIO_printf(bio_err, "Invalid KDF name %s\n", argv[0]);
109 ctx = EVP_KDF_CTX_new_id(id);
114 for (i = 0; i < sk_OPENSSL_STRING_num(opts); i++) {
115 char *opt = sk_OPENSSL_STRING_value(opts, i);
116 if (kdf_ctrl_string(ctx, opt) <= 0) {
117 BIO_printf(bio_err, "KDF parameter error '%s'\n", opt);
118 ERR_print_errors(bio_err);
124 out = bio_open_default(outfile, 'w', out_bin ? FORMAT_BINARY : FORMAT_TEXT);
129 BIO_printf(bio_err, "Invalid derived key length.\n");
132 dkm_bytes = app_malloc(dkm_len, "out buffer");
133 if (dkm_bytes == NULL)
136 if (!EVP_KDF_derive(ctx, dkm_bytes, dkm_len)) {
137 BIO_printf(bio_err, "EVP_KDF_derive failed\n");
142 BIO_write(out, dkm_bytes, dkm_len);
144 hexout = OPENSSL_buf2hexstr(dkm_bytes, dkm_len);
145 BIO_printf(out, "%s\n\n", hexout);
151 ERR_print_errors(bio_err);
152 OPENSSL_clear_free(dkm_bytes, dkm_len);
153 sk_OPENSSL_STRING_free(opts);
154 EVP_KDF_CTX_free(ctx);
156 OPENSSL_free(hexout);