openssl: AES-SIV EVP_DecryptUpdate() fails without setting error
(openssl-3.0.3)
I’m trying out AES-SIV. I’m using the test program below to try to decrypt the test vectors from RFC 5297 (test program also available at https://github.com/petere/test-openssl-aes-siv). The call to EVP_DecryptUpdate() (the second one, not the one for the AD) fails, but no error is set, so the output from the program is:
$ ./test-openssl-aes-siv
EVP_DecryptUpdate: (null) (0)
So, I’m probably doing something wrong (a hint would be welcome), but my point is that if the function fails it should set an error. My implementation of *printf apparently prints “(null)”, but in other circumstances this could also crash, which is bad.
I traced the calls like this: EVP_DecryptUpdate … siv_cipher … ossl_siv128_decrypt, and there it somehow fails, but no error is set, and the code is so terse that I cannot guess the reason.
#include <stdlib.h>
#include <openssl/err.h>
#include <openssl/evp.h>
unsigned char key[] = {
0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
};
unsigned char ad[] = {
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
};
unsigned char ciphertext[] = {
0x40, 0xc0, 0x2b, 0x96, 0x90, 0xc4, 0xdc, 0x04, 0xda, 0xef, 0x7f, 0x6a, 0xfe, 0x5c,
};
static void
test1(void)
{
EVP_CIPHER *cipher = EVP_CIPHER_fetch(NULL, "AES-128-SIV", NULL);
if (!cipher)
{
fprintf(stderr, "EVP_CIPHER_fetch: %s\n",
ERR_reason_error_string(ERR_get_error()));
exit(1);
}
EVP_CIPHER_CTX *evp_cipher_ctx = EVP_CIPHER_CTX_new();
if (!EVP_DecryptInit_ex(evp_cipher_ctx, cipher, NULL, NULL, NULL))
{
fprintf(stderr, "EVP_DecryptInit_ex: %s\n",
ERR_reason_error_string(ERR_get_error()));
exit(1);
}
/* key */
if (!EVP_DecryptInit_ex(evp_cipher_ctx, NULL, NULL, key, NULL))
{
fprintf(stderr, "EVP_DecryptInit_ex#2: %s\n",
ERR_reason_error_string(ERR_get_error()));
exit(1);
}
int decrlen;
/* AD */
if (!EVP_DecryptUpdate(evp_cipher_ctx, NULL, &decrlen, ad, sizeof(ad)))
{
fprintf(stderr, "EVP_DecryptUpdate[AD]: %s\n",
ERR_reason_error_string(ERR_get_error()));
exit(1);
}
unsigned char outbuf[1024];
if (!EVP_DecryptUpdate(evp_cipher_ctx, outbuf, &decrlen, ciphertext, sizeof(ciphertext)))
{
fprintf(stderr, "EVP_DecryptUpdate: %s (%lu)\n",
ERR_reason_error_string(ERR_get_error()), ERR_get_error());
exit(1);
}
int decrlen2;
if (!EVP_DecryptFinal_ex(evp_cipher_ctx, outbuf + decrlen, &decrlen2))
{
fprintf(stderr, "EVP_DecryptFinal_ex: %s\n",
ERR_reason_error_string(ERR_get_error()));
exit(1);
}
decrlen += decrlen2;
printf("plaintext = ");
for (int i = 0; i < decrlen; i++)
printf("0x%02x", outbuf[i]);
printf("\n");
}
int
main(void)
{
test1();
return 0;
}
About this issue
- Original URL
- State: open
- Created 2 years ago
- Comments: 15 (15 by maintainers)
Commits related to this issue
- Update SIV mode documentation Fixes #18440 — committed to tmshort/openssl by tmshort 2 years ago
- Update SIV mode documentation Fixes #18440 Reviewed-by: Shane Lontis <shane.lontis@oracle.com> Reviewed-by: Tomas Mraz <tomas@openssl.org> Reviewed-by: Paul Dale <pauli@openssl.org> (Merged from htt... — committed to openssl/openssl by tmshort 2 years ago
- Update SIV mode documentation Fixes #18440 Reviewed-by: Shane Lontis <shane.lontis@oracle.com> Reviewed-by: Tomas Mraz <tomas@openssl.org> Reviewed-by: Paul Dale <pauli@openssl.org> (Merged from htt... — committed to sftcd/openssl by tmshort 2 years ago
I remember seeing that BoringSSL has an
EVP_AEADfamily of APIs but I haven’t actually looked at them at all.I did start having a look at this also quite a while ago… I think it really needs a separate AEAD interface.