diff options
Diffstat (limited to 'src/aes256.c')
-rw-r--r-- | src/aes256.c | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/src/aes256.c b/src/aes256.c new file mode 100644 index 0000000..767cdb2 --- /dev/null +++ b/src/aes256.c | |||
@@ -0,0 +1,98 @@ | |||
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 | } | ||