31#include <openssl/evp.h>
32#include <openssl/rand.h>
41#define INPUT_BUFSIZE 4096
42#define WRAPKEY_BUFSIZE 32
44#define OBJECT_HEADER_SIZE 59
49 EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
50 const EVP_CIPHER *cipher_type;
60 cipher_type = EVP_aes_128_ccm();
64 cipher_type = EVP_aes_192_ccm();
68 cipher_type = EVP_aes_256_ccm();
75 if (RAND_bytes(nonce, nonce_len) != 1) {
79 memcpy(out, nonce, nonce_len);
82 if (EVP_EncryptInit_ex(ctx, cipher_type, NULL, NULL, NULL) != 1) {
87 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_IVLEN, nonce_len, NULL) != 1) {
92 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_TAG, tag_len, NULL) != 1) {
97 if (EVP_EncryptInit_ex(ctx, NULL, NULL, key, nonce) != 1) {
102 if (EVP_EncryptUpdate(ctx, NULL, &
len, NULL,
in_len) != 1) {
107 if (EVP_EncryptUpdate(ctx, out + nonce_len, &
len, in,
in_len) != 1) {
113 if (EVP_EncryptFinal_ex(ctx, out + nonce_len + *
out_len, &
len) != 1) {
119 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_GET_TAG, tag_len,
120 out + nonce_len + *
out_len) != 1) {
127 EVP_CIPHER_CTX_free(ctx);
132static void format_header(
yh_algorithm wrapkey_algorithm,
138 *header = (
uint8_t) wrapkey_algorithm;
147 *((
uint16_t *) header) = htons(data_len);
169static FILE *open_file(
const char *
name,
bool input) {
171 if (strcmp(
name,
"-") == 0) {
174 return fopen(
name,
"rb");
177 if (strcmp(
name,
"-") == 0) {
180 return fopen(
name,
"wb");
187 for (i = 0; i <
len; i++) {
189 fprintf(stderr,
"\n");
190 else if (i && !(i % 8))
191 fprintf(stderr,
" ");
192 fprintf(stderr,
"%02x",
buf[i]);
194 fprintf(stderr,
"\n");
198 struct gengetopt_args_info args_info;
200 int rc = EXIT_FAILURE;
203 FILE *input_file = NULL;
204 FILE *output_file = NULL;
205 FILE *wrapkey_file = NULL;
214 } wrap_object = {{{0}, {0}}};
216 size_t wrap_object_len =
sizeof(wrap_object.body);
218 if (cmdline_parser(argc,
argv, &args_info) != 0) {
225 fprintf(stderr,
"Unable to parse algorithm: %s\n",
yh_strerror(yhrc));
232 fprintf(stderr,
"Unable to parse capabilities: %s\n",
yh_strerror(yhrc));
239 fprintf(stderr,
"Unable to parse domains: %s\n",
yh_strerror(yhrc));
246 size_t label_len = strlen(args_info.label_arg);
249 "Unable to parse label: label too long, maximum length is %d\n",
257 fprintf(stderr,
"Invalid algorithm\n");
264 if (has_delegated ==
true) {
265 if (!args_info.delegated_given) {
266 fprintf(stderr,
"Missing delegated capabilities argument\n");
272 fprintf(stderr,
"Unable to parse delegated capabilities: %s\n",
278 input_file = open_file(args_info.in_arg,
true);
279 if (input_file == NULL) {
280 perror(
"Unable to open input file");
286 char password[256] = {0};
287 size_t password_len =
sizeof(
password);
289 if (input_file == stdin) {
290 const char *prompt =
"Derivation Password: ";
291 if (EVP_read_pw_string(password, password_len, prompt, 1)) {
292 fprintf(stderr,
"Unable to read password prompt\n");
295 password_len = strlen(password);
299 fprintf(stderr,
"Unable to read input file\n");
302 if (password[password_len - 1] ==
'\n') {
305 if (password[password_len - 1] ==
'\r') {
308 password[password_len] =
'\0';
313 PKCS5_PBKDF2_HMAC((
const char *) password, password_len,
317 fprintf(stderr,
"Unable to derive keys\n");
335 &wrap_object_len) ==
false) {
336 fprintf(stderr,
"Unable to read input file\n");
344 if (
read_file(input_file, wrap_object.body, &wrap_object_len) ==
false) {
345 fprintf(stderr,
"Unable to read input file\n");
350 wrap_object.body, &wrap_object_len,
true) !=
true) {
351 fprintf(stderr,
"Unable to read asymmetric private key\n");
356 fprintf(stderr,
"Mismatched algorithm\n");
362 if (
read_file(input_file, wrap_object.body, &wrap_object_len) ==
false) {
363 fprintf(stderr,
"Unable to read input file\n");
368 wrap_object.body, &wrap_object_len) !=
true) {
369 fprintf(stderr,
"Unable to format hmac key\n");
375 if (
read_file(input_file, wrap_object.body, &wrap_object_len) ==
false) {
376 fprintf(stderr,
"Unable to read input file\n");
381 wrapkey_file = open_file(args_info.wrapkey_arg,
true);
382 if (wrapkey_file == NULL) {
383 perror(
"Unable to open wrapkey file");
388 size_t wrapkey_buf_len =
sizeof(wrapkey_buf);
389 if (
read_file(wrapkey_file, wrapkey_buf, &wrapkey_buf_len) ==
false) {
390 fprintf(stderr,
"Unable to read wrapkey file\n");
394 switch (wrapkey_buf_len) {
405 fprintf(stderr,
"Unable to parse wrapkey: invalid length\n");
409 output_file = open_file(args_info.out_arg,
false);
410 if (output_file == NULL) {
411 perror(
"Unable to open output file");
419 size_t wrapped_len =
sizeof(wrapped);
421 if (wrap_data(wrapkey_buf, wrapkey_buf_len, wrap_object.buf,
423 &wrapped_len) ==
false) {
424 fprintf(stderr,
"Unable to wrap data\n");
428 if (getenv(
"DEBUG") != NULL) {
433 fprintf(stderr,
"Unable to write output file\n");
441 cmdline_parser_free(&args_info);
443 if (input_file != NULL) {
448 if (output_file != NULL) {
453 if (wrapkey_file != NULL) {
454 fclose(wrapkey_file);
const char * yh_strerror(yh_rc err)
void YH_INTERNAL dump_hex(FILE *file, const uint8_t *ptr, uint16_t len)
Capabilities representation.
uint8_t capabilities[YH_CAPABILITIES_LEN]
Capabilities is represented as an 8 byte uint8_t array.
bool split_hmac_key(yh_algorithm algorithm, uint8_t *in, size_t in_len, uint8_t *out, size_t *out_len)
bool algo2type(yh_algorithm algorithm, yh_object_type *type)
bool read_file(FILE *fp, uint8_t *buf, size_t *buf_len)
bool write_file(const uint8_t *buf, size_t buf_len, FILE *fp, format_t format)
bool read_private_key(uint8_t *buf, size_t len, yh_algorithm *algo, uint8_t *bytes, size_t *bytes_len, bool internal_repr)
#define OBJECT_HEADER_SIZE
yh_rc yh_string_to_domains(const char *domains, uint16_t *result)
yh_rc yh_string_to_capabilities(const char *capability, yh_capabilities *result)
yh_rc yh_string_to_algo(const char *string, yh_algorithm *algo)
#define YH_DEFAULT_ITERS
Number of iterations for PBKDF2 key derivation.
@ YH_HMAC_KEY
HMAC Key is a secret key used when computing and verifying HMAC signatures.
@ YH_ASYMMETRIC_KEY
Asymmetric Key is the private key of an asymmetric key-pair.
@ YH_AUTHENTICATION_KEY
Authentication Key is used to establish Sessions with a device.
#define YH_OBJ_LABEL_LEN
Max length of object labels.
@ YH_ALGO_AES256_CCM_WRAP
aes256-ccm-wrap
@ YH_ALGO_AES192_CCM_WRAP
aes192-ccm-wrap
@ YH_ALGO_AES128_CCM_WRAP
aes128-ccm-wrap
#define YH_DEFAULT_SALT
Salt to be used for PBKDF2 key derivation.
#define YH_KEY_LEN
Length of authentication keys.
#define YH_CAPABILITIES_LEN
Length of capabilities array.
@ YHR_SUCCESS
Returned value when function was successful.
yh_capabilities capabilities
session operation op sign key_len
memcpy((char *) pInfo->slotDescription, s, l)