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