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