1 1.1 christos /* 2 1.1 christos * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. 3 1.1 christos * 4 1.1 christos * Licensed under the Apache License 2.0 (the "License"). You may not use 5 1.1 christos * this file except in compliance with the License. You can obtain a copy 6 1.1 christos * in the file LICENSE in the source distribution or at 7 1.1 christos * https://www.openssl.org/source/license.html 8 1.1 christos */ 9 1.1 christos 10 1.1 christos #include <string.h> 11 1.1 christos 12 1.1 christos #include "apps.h" 13 1.1 christos #include "progs.h" 14 1.1 christos #include <openssl/bio.h> 15 1.1 christos #include <openssl/err.h> 16 1.1 christos #include <openssl/evp.h> 17 1.1 christos #include <openssl/kdf.h> 18 1.1 christos #include <openssl/params.h> 19 1.1 christos 20 1.1 christos typedef enum OPTION_choice { 21 1.1 christos OPT_COMMON, 22 1.1 christos OPT_KDFOPT, OPT_BIN, OPT_KEYLEN, OPT_OUT, 23 1.1 christos OPT_CIPHER, OPT_DIGEST, OPT_MAC, 24 1.1 christos OPT_PROV_ENUM 25 1.1 christos } OPTION_CHOICE; 26 1.1 christos 27 1.1 christos const OPTIONS kdf_options[] = { 28 1.1 christos {OPT_HELP_STR, 1, '-', "Usage: %s [options] kdf_name\n"}, 29 1.1 christos 30 1.1 christos OPT_SECTION("General"), 31 1.1 christos {"help", OPT_HELP, '-', "Display this summary"}, 32 1.1 christos {"kdfopt", OPT_KDFOPT, 's', "KDF algorithm control parameters in n:v form"}, 33 1.1 christos {"cipher", OPT_CIPHER, 's', "Cipher"}, 34 1.1 christos {"digest", OPT_DIGEST, 's', "Digest"}, 35 1.1 christos {"mac", OPT_MAC, 's', "MAC"}, 36 1.1 christos {OPT_MORE_STR, 1, '-', "See 'Supported Controls' in the EVP_KDF_ docs\n"}, 37 1.1 christos {"keylen", OPT_KEYLEN, 's', "The size of the output derived key"}, 38 1.1 christos 39 1.1 christos OPT_SECTION("Output"), 40 1.1 christos {"out", OPT_OUT, '>', "Output to filename rather than stdout"}, 41 1.1 christos {"binary", OPT_BIN, '-', 42 1.1 christos "Output in binary format (default is hexadecimal)"}, 43 1.1 christos 44 1.1 christos OPT_PROV_OPTIONS, 45 1.1 christos 46 1.1 christos OPT_PARAMETERS(), 47 1.1 christos {"kdf_name", 0, 0, "Name of the KDF algorithm"}, 48 1.1 christos {NULL} 49 1.1 christos }; 50 1.1 christos 51 1.1 christos static char *alloc_kdf_algorithm_name(STACK_OF(OPENSSL_STRING) **optp, 52 1.1 christos const char *name, const char *arg) 53 1.1 christos { 54 1.1 christos size_t len = strlen(name) + strlen(arg) + 2; 55 1.1 christos char *res; 56 1.1 christos 57 1.1 christos if (*optp == NULL) 58 1.1 christos *optp = sk_OPENSSL_STRING_new_null(); 59 1.1 christos if (*optp == NULL) 60 1.1 christos return NULL; 61 1.1 christos 62 1.1 christos res = app_malloc(len, "algorithm name"); 63 1.1 christos BIO_snprintf(res, len, "%s:%s", name, arg); 64 1.1 christos if (sk_OPENSSL_STRING_push(*optp, res)) 65 1.1 christos return res; 66 1.1 christos OPENSSL_free(res); 67 1.1 christos return NULL; 68 1.1 christos } 69 1.1 christos 70 1.1 christos int kdf_main(int argc, char **argv) 71 1.1 christos { 72 1.1 christos int ret = 1, out_bin = 0; 73 1.1 christos OPTION_CHOICE o; 74 1.1 christos STACK_OF(OPENSSL_STRING) *opts = NULL; 75 1.1 christos char *prog, *hexout = NULL; 76 1.1 christos const char *outfile = NULL; 77 1.1 christos unsigned char *dkm_bytes = NULL; 78 1.1 christos size_t dkm_len = 0; 79 1.1 christos BIO *out = NULL; 80 1.1 christos EVP_KDF *kdf = NULL; 81 1.1 christos EVP_KDF_CTX *ctx = NULL; 82 1.1 christos char *digest = NULL, *cipher = NULL, *mac = NULL; 83 1.1 christos 84 1.1 christos prog = opt_init(argc, argv, kdf_options); 85 1.1 christos while ((o = opt_next()) != OPT_EOF) { 86 1.1 christos switch (o) { 87 1.1 christos default: 88 1.1 christos opthelp: 89 1.1 christos BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); 90 1.1 christos goto err; 91 1.1 christos case OPT_HELP: 92 1.1 christos opt_help(kdf_options); 93 1.1 christos ret = 0; 94 1.1 christos goto err; 95 1.1 christos case OPT_BIN: 96 1.1 christos out_bin = 1; 97 1.1 christos break; 98 1.1 christos case OPT_KEYLEN: 99 1.1 christos dkm_len = (size_t)atoi(opt_arg()); 100 1.1 christos break; 101 1.1 christos case OPT_OUT: 102 1.1 christos outfile = opt_arg(); 103 1.1 christos break; 104 1.1 christos case OPT_KDFOPT: 105 1.1 christos if (opts == NULL) 106 1.1 christos opts = sk_OPENSSL_STRING_new_null(); 107 1.1 christos if (opts == NULL || !sk_OPENSSL_STRING_push(opts, opt_arg())) 108 1.1 christos goto opthelp; 109 1.1 christos break; 110 1.1 christos case OPT_CIPHER: 111 1.1 christos OPENSSL_free(cipher); 112 1.1 christos cipher = alloc_kdf_algorithm_name(&opts, "cipher", opt_arg()); 113 1.1 christos if (cipher == NULL) 114 1.1 christos goto opthelp; 115 1.1 christos break; 116 1.1 christos case OPT_DIGEST: 117 1.1 christos OPENSSL_free(digest); 118 1.1 christos digest = alloc_kdf_algorithm_name(&opts, "digest", opt_arg()); 119 1.1 christos if (digest == NULL) 120 1.1 christos goto opthelp; 121 1.1 christos break; 122 1.1 christos case OPT_MAC: 123 1.1 christos OPENSSL_free(mac); 124 1.1 christos mac = alloc_kdf_algorithm_name(&opts, "mac", opt_arg()); 125 1.1 christos if (mac == NULL) 126 1.1 christos goto opthelp; 127 1.1 christos break; 128 1.1 christos case OPT_PROV_CASES: 129 1.1 christos if (!opt_provider(o)) 130 1.1 christos goto err; 131 1.1 christos break; 132 1.1 christos } 133 1.1 christos } 134 1.1 christos 135 1.1 christos /* One argument, the KDF name. */ 136 1.1 christos argc = opt_num_rest(); 137 1.1 christos argv = opt_rest(); 138 1.1 christos if (argc != 1) 139 1.1 christos goto opthelp; 140 1.1 christos 141 1.1 christos if ((kdf = EVP_KDF_fetch(app_get0_libctx(), argv[0], 142 1.1 christos app_get0_propq())) == NULL) { 143 1.1 christos BIO_printf(bio_err, "Invalid KDF name %s\n", argv[0]); 144 1.1 christos goto opthelp; 145 1.1 christos } 146 1.1 christos 147 1.1 christos ctx = EVP_KDF_CTX_new(kdf); 148 1.1 christos if (ctx == NULL) 149 1.1 christos goto err; 150 1.1 christos 151 1.1 christos if (opts != NULL) { 152 1.1 christos int ok = 1; 153 1.1 christos OSSL_PARAM *params = 154 1.1 christos app_params_new_from_opts(opts, EVP_KDF_settable_ctx_params(kdf)); 155 1.1 christos 156 1.1 christos if (params == NULL) 157 1.1 christos goto err; 158 1.1 christos 159 1.1 christos if (!EVP_KDF_CTX_set_params(ctx, params)) { 160 1.1 christos BIO_printf(bio_err, "KDF parameter error\n"); 161 1.1 christos ERR_print_errors(bio_err); 162 1.1 christos ok = 0; 163 1.1 christos } 164 1.1 christos app_params_free(params); 165 1.1 christos if (!ok) 166 1.1 christos goto err; 167 1.1 christos } 168 1.1 christos 169 1.1 christos out = bio_open_default(outfile, 'w', out_bin ? FORMAT_BINARY : FORMAT_TEXT); 170 1.1 christos if (out == NULL) 171 1.1 christos goto err; 172 1.1 christos 173 1.1 christos if (dkm_len <= 0) { 174 1.1 christos BIO_printf(bio_err, "Invalid derived key length.\n"); 175 1.1 christos goto err; 176 1.1 christos } 177 1.1 christos dkm_bytes = app_malloc(dkm_len, "out buffer"); 178 1.1 christos if (dkm_bytes == NULL) 179 1.1 christos goto err; 180 1.1 christos 181 1.1 christos if (!EVP_KDF_derive(ctx, dkm_bytes, dkm_len, NULL)) { 182 1.1 christos BIO_printf(bio_err, "EVP_KDF_derive failed\n"); 183 1.1 christos goto err; 184 1.1 christos } 185 1.1 christos 186 1.1 christos if (out_bin) { 187 1.1 christos BIO_write(out, dkm_bytes, dkm_len); 188 1.1 christos } else { 189 1.1 christos hexout = OPENSSL_buf2hexstr(dkm_bytes, dkm_len); 190 1.1 christos if (hexout == NULL) { 191 1.1 christos BIO_printf(bio_err, "Memory allocation failure\n"); 192 1.1 christos goto err; 193 1.1 christos } 194 1.1 christos BIO_printf(out, "%s\n\n", hexout); 195 1.1 christos } 196 1.1 christos 197 1.1 christos ret = 0; 198 1.1 christos err: 199 1.1 christos if (ret != 0) 200 1.1 christos ERR_print_errors(bio_err); 201 1.1 christos OPENSSL_clear_free(dkm_bytes, dkm_len); 202 1.1 christos sk_OPENSSL_STRING_free(opts); 203 1.1 christos EVP_KDF_free(kdf); 204 1.1 christos EVP_KDF_CTX_free(ctx); 205 1.1 christos BIO_free(out); 206 1.1 christos OPENSSL_free(hexout); 207 1.1 christos OPENSSL_free(cipher); 208 1.1 christos OPENSSL_free(digest); 209 1.1 christos OPENSSL_free(mac); 210 1.1 christos return ret; 211 1.1 christos } 212