Compare commits
2 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8752f78be1 | ||
|
|
c5bcf99184 |
2 changed files with 235 additions and 3 deletions
228
yubihsm-shell-2.7.0-session-leak.patch
Normal file
228
yubihsm-shell-2.7.0-session-leak.patch
Normal file
|
|
@ -0,0 +1,228 @@
|
|||
diff --git a/aes_cmac/aes.c b/aes_cmac/aes.c
|
||||
index 5b5f45f..696a289 100644
|
||||
--- a/aes_cmac/aes.c
|
||||
+++ b/aes_cmac/aes.c
|
||||
@@ -170,77 +170,15 @@ cleanup:
|
||||
|
||||
#else
|
||||
|
||||
-static const EVP_CIPHER *aes_ecb(uint16_t key_len) {
|
||||
- switch (key_len) {
|
||||
- case 16:
|
||||
- return EVP_aes_128_ecb();
|
||||
- case 24:
|
||||
- return EVP_aes_192_ecb();
|
||||
- case 32:
|
||||
- return EVP_aes_256_ecb();
|
||||
- default:
|
||||
- return NULL;
|
||||
- }
|
||||
-}
|
||||
-
|
||||
-static const EVP_CIPHER *aes_cbc(uint16_t key_len) {
|
||||
- switch (key_len) {
|
||||
- case 16:
|
||||
- return EVP_aes_128_cbc();
|
||||
- case 24:
|
||||
- return EVP_aes_192_cbc();
|
||||
- case 32:
|
||||
- return EVP_aes_256_cbc();
|
||||
- default:
|
||||
- return NULL;
|
||||
- }
|
||||
-}
|
||||
-
|
||||
-static int aes_encrypt_ex(const EVP_CIPHER *cipher, const uint8_t *in,
|
||||
- uint8_t *out, uint16_t len, const uint8_t *iv,
|
||||
- aes_context *ctx) {
|
||||
- if (EVP_EncryptInit_ex(ctx->ctx, cipher, NULL, ctx->key, iv) != 1) {
|
||||
- return -1;
|
||||
- }
|
||||
- if (EVP_CIPHER_CTX_set_padding(ctx->ctx, 0) != 1) {
|
||||
- return -2;
|
||||
- }
|
||||
- int update_len = len;
|
||||
- if (EVP_EncryptUpdate(ctx->ctx, out, &update_len, in, len) != 1) {
|
||||
- return -3;
|
||||
- }
|
||||
- int final_len = len - update_len;
|
||||
- if (EVP_EncryptFinal_ex(ctx->ctx, out + update_len, &final_len) != 1) {
|
||||
- return -4;
|
||||
- }
|
||||
- if (update_len + final_len != len) {
|
||||
- return -5;
|
||||
- }
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-static int aes_decrypt_ex(const EVP_CIPHER *cipher, const uint8_t *in,
|
||||
- uint8_t *out, uint16_t len, const uint8_t *iv,
|
||||
- aes_context *ctx) {
|
||||
- if (EVP_DecryptInit_ex(ctx->ctx, cipher, NULL, ctx->key, iv) != 1) {
|
||||
- return -1;
|
||||
- }
|
||||
- if (EVP_CIPHER_CTX_set_padding(ctx->ctx, 0) != 1) {
|
||||
- return -2;
|
||||
- }
|
||||
- int update_len = len;
|
||||
- if (EVP_DecryptUpdate(ctx->ctx, out, &update_len, in, len) != 1) {
|
||||
- return -3;
|
||||
- }
|
||||
- int final_len = len - update_len;
|
||||
- if (EVP_DecryptFinal_ex(ctx->ctx, out + update_len, &final_len) != 1) {
|
||||
- return -4;
|
||||
- }
|
||||
- if (update_len + final_len != len) {
|
||||
- return -5;
|
||||
- }
|
||||
- return 0;
|
||||
-}
|
||||
+/*
|
||||
+ * Use the low-level AES API (AES_set_encrypt_key / AES_ecb_encrypt /
|
||||
+ * AES_cbc_encrypt) instead of the EVP API. The low-level functions
|
||||
+ * operate directly on an AES_KEY struct with pre-computed round keys
|
||||
+ * and do not depend on OpenSSL's global library context. This means
|
||||
+ * they continue to work after OPENSSL_cleanup() has been called,
|
||||
+ * which is critical for SCP03 session close during application
|
||||
+ * teardown.
|
||||
+ */
|
||||
|
||||
#endif
|
||||
|
||||
@@ -266,17 +204,15 @@ int aes_set_key(const uint8_t *key, uint16_t key_len, aes_context *ctx) {
|
||||
|
||||
#else
|
||||
|
||||
- if (key == NULL || aes_ecb(key_len) == NULL) {
|
||||
+ if (key == NULL || (key_len != 16 && key_len != 24 && key_len != 32)) {
|
||||
return -1;
|
||||
}
|
||||
- if (!ctx->ctx) {
|
||||
- ctx->ctx = EVP_CIPHER_CTX_new();
|
||||
- if (!ctx->ctx) {
|
||||
- return -2;
|
||||
- }
|
||||
+ if (AES_set_encrypt_key(key, key_len * 8, &ctx->enc_key) != 0) {
|
||||
+ return -2;
|
||||
+ }
|
||||
+ if (AES_set_decrypt_key(key, key_len * 8, &ctx->dec_key) != 0) {
|
||||
+ return -3;
|
||||
}
|
||||
- ctx->key_len = key_len;
|
||||
- memcpy(ctx->key, key, key_len);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -295,23 +231,18 @@ int aes_load_key(const char *key, aes_context *ctx) {
|
||||
const uint8_t default_mac[] = {0x59, 0x2f, 0xd4, 0x83, 0xf7, 0x59,
|
||||
0xe2, 0x99, 0x09, 0xa0, 0x4c, 0x45,
|
||||
0x05, 0xd2, 0xce, 0x0a};
|
||||
- ctx->key_len = sizeof(default_enc);
|
||||
- if (key == NULL || aes_ecb(ctx->key_len) == NULL) {
|
||||
+ const uint8_t *k;
|
||||
+
|
||||
+ if (key == NULL)
|
||||
return -1;
|
||||
- }
|
||||
- if (!ctx->ctx) {
|
||||
- ctx->ctx = EVP_CIPHER_CTX_new();
|
||||
- if (!ctx->ctx) {
|
||||
- return -2;
|
||||
- }
|
||||
- }
|
||||
if (!strcmp(key, "default_enc"))
|
||||
- memcpy(ctx->key, default_enc, ctx->key_len);
|
||||
+ k = default_enc;
|
||||
else if (!strcmp(key, "default_mac"))
|
||||
- memcpy(ctx->key, default_mac, ctx->key_len);
|
||||
+ k = default_mac;
|
||||
else
|
||||
- memset(ctx->key, 0, ctx->key_len);
|
||||
- return 0;
|
||||
+ return -1;
|
||||
+
|
||||
+ return aes_set_key(k, sizeof(default_enc), ctx);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -334,8 +265,8 @@ int aes_encrypt(const uint8_t *in, uint8_t *out, aes_context *ctx) {
|
||||
|
||||
#else
|
||||
|
||||
- return aes_encrypt_ex(aes_ecb(ctx->key_len), in, out, AES_BLOCK_SIZE, NULL,
|
||||
- ctx);
|
||||
+ AES_ecb_encrypt(in, out, &ctx->enc_key, AES_ENCRYPT);
|
||||
+ return 0;
|
||||
|
||||
#endif
|
||||
}
|
||||
@@ -359,8 +290,8 @@ int aes_decrypt(const uint8_t *in, uint8_t *out, aes_context *ctx) {
|
||||
|
||||
#else
|
||||
|
||||
- return aes_decrypt_ex(aes_ecb(ctx->key_len), in, out, AES_BLOCK_SIZE, NULL,
|
||||
- ctx);
|
||||
+ AES_ecb_encrypt(in, out, &ctx->dec_key, AES_DECRYPT);
|
||||
+ return 0;
|
||||
|
||||
#endif
|
||||
}
|
||||
@@ -388,7 +319,10 @@ int aes_cbc_encrypt(const uint8_t *in, uint8_t *out, uint16_t len,
|
||||
|
||||
#else
|
||||
|
||||
- return aes_encrypt_ex(aes_cbc(ctx->key_len), in, out, len, iv, ctx);
|
||||
+ uint8_t _iv[AES_BLOCK_SIZE];
|
||||
+ memcpy(_iv, iv, AES_BLOCK_SIZE);
|
||||
+ AES_cbc_encrypt(in, out, len, &ctx->enc_key, _iv, AES_ENCRYPT);
|
||||
+ return 0;
|
||||
|
||||
#endif
|
||||
}
|
||||
@@ -416,7 +350,10 @@ int aes_cbc_decrypt(const uint8_t *in, uint8_t *out, uint16_t len,
|
||||
|
||||
#else
|
||||
|
||||
- return aes_decrypt_ex(aes_cbc(ctx->key_len), in, out, len, iv, ctx);
|
||||
+ uint8_t _iv[AES_BLOCK_SIZE];
|
||||
+ memcpy(_iv, iv, AES_BLOCK_SIZE);
|
||||
+ AES_cbc_encrypt(in, out, len, &ctx->dec_key, _iv, AES_DECRYPT);
|
||||
+ return 0;
|
||||
|
||||
#endif
|
||||
}
|
||||
@@ -484,7 +421,7 @@ void aes_destroy(aes_context *ctx) {
|
||||
|
||||
#else
|
||||
|
||||
- EVP_CIPHER_CTX_free(ctx->ctx);
|
||||
+ /* AES_KEY has no resources to free, just zero the key material */
|
||||
|
||||
#endif
|
||||
|
||||
diff --git a/aes_cmac/aes.h b/aes_cmac/aes.h
|
||||
index 798cb15..ba0ef97 100644
|
||||
--- a/aes_cmac/aes.h
|
||||
+++ b/aes_cmac/aes.h
|
||||
@@ -30,7 +30,7 @@
|
||||
#include <bcrypt.h>
|
||||
#include <ntstatus.h>
|
||||
#else
|
||||
-#include <openssl/evp.h>
|
||||
+#include <openssl/aes.h>
|
||||
#endif
|
||||
|
||||
#ifndef AES_BLOCK_SIZE // Defined in openssl/aes.h
|
||||
@@ -51,9 +51,8 @@ typedef struct {
|
||||
PBYTE pbKeyECBObj;
|
||||
size_t cbKeyObj;
|
||||
#else
|
||||
- EVP_CIPHER_CTX *ctx;
|
||||
- uint16_t key_len;
|
||||
- uint8_t key[32];
|
||||
+ AES_KEY enc_key;
|
||||
+ AES_KEY dec_key;
|
||||
#endif
|
||||
} aes_context;
|
||||
|
||||
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
Name: yubihsm-shell
|
||||
Version: 2.7.0
|
||||
Release: 2%{?dist}
|
||||
Release: 3%{?dist}
|
||||
Summary: Tools to interact with YubiHSM 2
|
||||
|
||||
# Automatically converted from old format: ASL 2.0 - review is highly recommended.
|
||||
|
|
@ -13,6 +13,8 @@ Source1: https://developers.yubico.com/%{name}/Releases/%{name}-%{version}.tar.g
|
|||
Source2: gpgkey-9588EA0F.gpg
|
||||
# https://github.com/Yubico/yubihsm-shell/pull/411
|
||||
Patch2: yubihsm-shell-2.5.0-pcsc-lite.patch
|
||||
# https://github.com/Yubico/yubihsm-shell/pull/528
|
||||
Patch3: yubihsm-shell-2.7.0-session-leak.patch
|
||||
|
||||
BuildRequires: cmake
|
||||
BuildRequires: cppcheck
|
||||
|
|
@ -45,8 +47,7 @@ Development libraries for working with yubihsm 2.
|
|||
|
||||
%prep
|
||||
gpgv2 --quiet --keyring %{SOURCE2} %{SOURCE1} %{SOURCE0}
|
||||
%setup -q
|
||||
%patch 2 -p1
|
||||
%autosetup -p1
|
||||
|
||||
|
||||
%build
|
||||
|
|
@ -112,6 +113,9 @@ chrpath --delete $RPM_BUILD_ROOT%{_libdir}/pkcs11/yubihsm_pkcs11.so
|
|||
|
||||
|
||||
%changelog
|
||||
* Tue Jun 23 2026 Jakub Jelen <jjelen@redhat.com> - 2.7.0-3
|
||||
- Use low-level AES operations to prevent session leak (#2487009)
|
||||
|
||||
* Fri Jul 25 2025 Fedora Release Engineering <releng@fedoraproject.org> - 2.7.0-2
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue