xref: /openbsd/lib/libfido2/src/aes256.c (revision 09467b48)
1 /*
2  * Copyright (c) 2018 Yubico AB. All rights reserved.
3  * Use of this source code is governed by a BSD-style
4  * license that can be found in the LICENSE file.
5  */
6 
7 #include <openssl/evp.h>
8 #include <string.h>
9 
10 #include "fido.h"
11 
12 int
13 aes256_cbc_enc(const fido_blob_t *key, const fido_blob_t *in, fido_blob_t *out)
14 {
15 	EVP_CIPHER_CTX	*ctx = NULL;
16 	unsigned char	 iv[32];
17 	int		 len;
18 	int		 ok = -1;
19 
20 	memset(iv, 0, sizeof(iv));
21 	out->ptr = NULL;
22 	out->len = 0;
23 
24 	/* sanity check */
25 	if (in->len > INT_MAX || (in->len % 16) != 0 ||
26 	    (out->ptr = calloc(1, in->len)) == NULL) {
27 		fido_log_debug("%s: in->len=%zu", __func__, in->len);
28 		goto fail;
29 	}
30 
31 	if ((ctx = EVP_CIPHER_CTX_new()) == NULL || key->len != 32 ||
32 	    !EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key->ptr, iv) ||
33 	    !EVP_CIPHER_CTX_set_padding(ctx, 0) ||
34 	    !EVP_EncryptUpdate(ctx, out->ptr, &len, in->ptr, (int)in->len) ||
35 	    len < 0 || (size_t)len != in->len) {
36 		fido_log_debug("%s: EVP_Encrypt", __func__);
37 		goto fail;
38 	}
39 
40 	out->len = (size_t)len;
41 
42 	ok = 0;
43 fail:
44 	if (ctx != NULL)
45 		EVP_CIPHER_CTX_free(ctx);
46 
47 	if (ok < 0) {
48 		free(out->ptr);
49 		out->ptr = NULL;
50 		out->len = 0;
51 	}
52 
53 	return (ok);
54 }
55 
56 int
57 aes256_cbc_dec(const fido_blob_t *key, const fido_blob_t *in, fido_blob_t *out)
58 {
59 	EVP_CIPHER_CTX	*ctx = NULL;
60 	unsigned char	 iv[32];
61 	int		 len;
62 	int		 ok = -1;
63 
64 	memset(iv, 0, sizeof(iv));
65 	out->ptr = NULL;
66 	out->len = 0;
67 
68 	/* sanity check */
69 	if (in->len > INT_MAX || (in->len % 16) != 0 ||
70 	    (out->ptr = calloc(1, in->len)) == NULL) {
71 		fido_log_debug("%s: in->len=%zu", __func__, in->len);
72 		goto fail;
73 	}
74 
75 	if ((ctx = EVP_CIPHER_CTX_new()) == NULL || key->len != 32 ||
76 	    !EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key->ptr, iv) ||
77 	    !EVP_CIPHER_CTX_set_padding(ctx, 0) ||
78 	    !EVP_DecryptUpdate(ctx, out->ptr, &len, in->ptr, (int)in->len) ||
79 	    len < 0 || (size_t)len > in->len + 32) {
80 		fido_log_debug("%s: EVP_Decrypt", __func__);
81 		goto fail;
82 	}
83 
84 	out->len = (size_t)len;
85 
86 	ok = 0;
87 fail:
88 	if (ctx != NULL)
89 		EVP_CIPHER_CTX_free(ctx);
90 
91 	if (ok < 0) {
92 		free(out->ptr);
93 		out->ptr = NULL;
94 		out->len = 0;
95 	}
96 
97 	return (ok);
98 }
99