]> git.ipfire.org Git - thirdparty/openssl.git/blame - apps/kdf.c
Documentation updates in light of the KDF conversion
[thirdparty/openssl.git] / apps / kdf.c
CommitLineData
c54492ec
SL
1/*
2 * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
3 *
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
8 */
9
10#include <string.h>
11
12#include "apps.h"
13#include "progs.h"
14#include <openssl/bio.h>
15#include <openssl/err.h>
16#include <openssl/evp.h>
17#include <openssl/kdf.h>
18
19typedef enum OPTION_choice {
20 OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
21 OPT_KDFOPT, OPT_BIN, OPT_KEYLEN, OPT_OUT
22} OPTION_CHOICE;
23
24const 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 "
33 "output)"},
34 {NULL}
35};
36
37static int kdf_ctrl_string(EVP_KDF_CTX *ctx, const char *value)
38{
39 int rv;
40 char *stmp, *vtmp = NULL;
41
42 stmp = OPENSSL_strdup(value);
43 if (stmp == NULL)
44 return -1;
45 vtmp = strchr(stmp, ':');
46 if (vtmp != NULL) {
47 *vtmp = 0;
48 vtmp++;
49 }
50 rv = EVP_KDF_ctrl_str(ctx, stmp, vtmp);
51 OPENSSL_free(stmp);
52 return rv;
53}
54
55int kdf_main(int argc, char **argv)
56{
57 int ret = 1, i, id, out_bin = 0;
58 OPTION_CHOICE o;
59 STACK_OF(OPENSSL_STRING) *opts = NULL;
60 char *prog, *hexout = NULL;
61 const char *outfile = NULL;
62 unsigned char *dkm_bytes = NULL;
63 size_t dkm_len = 0;
64 BIO *out = NULL;
65 EVP_KDF_CTX *ctx = NULL;
66
67 prog = opt_init(argc, argv, kdf_options);
68 while ((o = opt_next()) != OPT_EOF) {
69 switch (o) {
70 default:
71opthelp:
72 BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
73 goto err;
74 case OPT_HELP:
75 opt_help(kdf_options);
76 ret = 0;
77 goto err;
78 case OPT_BIN:
79 out_bin = 1;
80 break;
81 case OPT_KEYLEN:
82 dkm_len = (size_t)atoi(opt_arg());
83 break;
84 case OPT_OUT:
85 outfile = opt_arg();
86 break;
87 case OPT_KDFOPT:
88 if (opts == NULL)
89 opts = sk_OPENSSL_STRING_new_null();
90 if (opts == NULL || !sk_OPENSSL_STRING_push(opts, opt_arg()))
91 goto opthelp;
92 break;
93 }
94 }
95 argc = opt_num_rest();
96 argv = opt_rest();
97
98 if (argc != 1) {
99 BIO_printf(bio_err, "Invalid number of extra arguments\n");
100 goto opthelp;
101 }
102
103 id = OBJ_sn2nid(argv[0]);
104 if (id == NID_undef) {
105 BIO_printf(bio_err, "Invalid KDF name %s\n", argv[0]);
106 goto opthelp;
107 }
108
109 ctx = EVP_KDF_CTX_new_id(id);
110 if (ctx == NULL)
111 goto err;
112
113 if (opts != NULL) {
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);
119 goto err;
120 }
121 }
122 }
123
124 out = bio_open_default(outfile, 'w', out_bin ? FORMAT_BINARY : FORMAT_TEXT);
125 if (out == NULL)
126 goto err;
127
128 if (dkm_len <= 0) {
129 BIO_printf(bio_err, "Invalid derived key length.\n");
130 goto err;
131 }
132 dkm_bytes = app_malloc(dkm_len, "out buffer");
133 if (dkm_bytes == NULL)
134 goto err;
135
136 if (!EVP_KDF_derive(ctx, dkm_bytes, dkm_len)) {
137 BIO_printf(bio_err, "EVP_KDF_derive failed\n");
138 goto err;
139 }
140
141 if (out_bin) {
142 BIO_write(out, dkm_bytes, dkm_len);
143 } else {
144 hexout = OPENSSL_buf2hexstr(dkm_bytes, dkm_len);
145 BIO_printf(out, "%s\n\n", hexout);
146 }
147
148 ret = 0;
149err:
150 if (ret != 0)
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);
155 BIO_free(out);
156 OPENSSL_free(hexout);
157 return ret;
158}