commit 6618edbe6686495829d6ac8c8f6a2860e9848127 Author: MSVSphere Packaging Team Date: Fri Mar 29 16:06:13 2024 +0300 import opencryptoki-3.22.0-3.el8 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9c75c19 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/opencryptoki-3.22.0.tar.gz diff --git a/.opencryptoki.metadata b/.opencryptoki.metadata new file mode 100644 index 0000000..b96efa9 --- /dev/null +++ b/.opencryptoki.metadata @@ -0,0 +1 @@ +4618b82afde56a8177e888c26d336c6f521bed8a SOURCES/opencryptoki-3.22.0.tar.gz diff --git a/SOURCES/opencryptoki-3.11.0-lockdir.patch b/SOURCES/opencryptoki-3.11.0-lockdir.patch new file mode 100644 index 0000000..936a654 --- /dev/null +++ b/SOURCES/opencryptoki-3.11.0-lockdir.patch @@ -0,0 +1,12 @@ +diff -up opencryptoki-3.11.0/configure.ac.me opencryptoki-3.11.0/configure.ac +--- opencryptoki-3.11.0/configure.ac.me 2019-01-30 17:10:19.660952694 +0100 ++++ opencryptoki-3.11.0/configure.ac 2019-01-30 17:13:54.150089964 +0100 +@@ -62,7 +62,7 @@ AC_SUBST([OPENLDAP_LIBS]) + + dnl Define custom variables + +-lockdir=$localstatedir/lock/opencryptoki ++lockdir=/run/lock/opencryptoki + AC_SUBST(lockdir) + + logdir=$localstatedir/log/opencryptoki diff --git a/SOURCES/opencryptoki-3.21-sandboxing.patch b/SOURCES/opencryptoki-3.21-sandboxing.patch new file mode 100644 index 0000000..b3ba3e5 --- /dev/null +++ b/SOURCES/opencryptoki-3.21-sandboxing.patch @@ -0,0 +1,27 @@ +diff -up opencryptoki-3.21.0/misc/pkcsslotd.service.in.me opencryptoki-3.21.0/misc/pkcsslotd.service.in +--- opencryptoki-3.21.0/misc/pkcsslotd.service.in.me 2023-05-16 20:50:08.128841932 +0200 ++++ opencryptoki-3.21.0/misc/pkcsslotd.service.in 2023-05-16 21:19:35.208570589 +0200 +@@ -22,17 +22,17 @@ PrivateUsers=no + PrivateNetwork=no + RestrictAddressFamilies=AF_UNIX AF_NETLINK + IPAddressDeny=any +-ProtectClock=yes ++#ProtectClock=yes + ProtectKernelTunables=yes + ProtectKernelModules=yes +-ProtectKernelLogs=yes ++#ProtectKernelLogs=yes + ProtectControlGroups=yes + ProtectHome=yes +-ProtectHostname=yes +-ProtectProc=default ++#ProtectHostname=yes ++#ProtectProc=default + ProtectSystem=strict +-ReadWritePaths=@localstatedir@ +-ProcSubset=all ++ReadWritePaths=@localstatedir@ /run ++#ProcSubset=all + MemoryDenyWriteExecute=yes + RestrictRealtime=yes + RestrictNamespaces=yes diff --git a/SOURCES/opencryptoki-3.21.0-p11sak.patch b/SOURCES/opencryptoki-3.21.0-p11sak.patch new file mode 100644 index 0000000..197ad52 --- /dev/null +++ b/SOURCES/opencryptoki-3.21.0-p11sak.patch @@ -0,0 +1,37 @@ +diff -up opencryptoki-3.21.0/Makefile.am.me opencryptoki-3.21.0/Makefile.am +--- opencryptoki-3.21.0/Makefile.am.me 2023-05-15 17:01:04.932616030 +0200 ++++ opencryptoki-3.21.0/Makefile.am 2023-05-15 17:00:45.732131601 +0200 +@@ -39,15 +39,8 @@ include tools/tools.mk + include doc/doc.mk + + install-data-hook: +- getent group $(pkcs_group) > /dev/null || $(GROUPADD) -r $(pkcs_group) +- getent passwd $(pkcsslotd_user) >/dev/null || $(USERADD) -r -g $(pkcs_group) -d /run/opencryptoki -s /sbin/nologin -c "Opencryptoki pkcsslotd user" $(pkcsslotd_user) + $(MKDIR_P) $(DESTDIR)/run/opencryptoki/ +- $(CHOWN) $(pkcsslotd_user):$(pkcs_group) $(DESTDIR)/run/opencryptoki/ +- $(CHGRP) $(pkcs_group) $(DESTDIR)/run/opencryptoki/ +- $(CHMOD) 0710 $(DESTDIR)/run/opencryptoki/ + $(MKDIR_P) $(DESTDIR)$(localstatedir)/lib/opencryptoki +- $(CHGRP) $(pkcs_group) $(DESTDIR)$(localstatedir)/lib/opencryptoki +- $(CHMOD) 0770 $(DESTDIR)$(localstatedir)/lib/opencryptoki + if ENABLE_LIBRARY + $(MKDIR_P) $(DESTDIR)$(libdir)/opencryptoki/stdll + $(MKDIR_P) $(DESTDIR)$(libdir)/pkcs11 +@@ -100,7 +93,7 @@ if ENABLE_EP11TOK + endif + if ENABLE_P11SAK + test -f $(DESTDIR)$(sysconfdir)/opencryptoki || $(MKDIR_P) $(DESTDIR)$(sysconfdir)/opencryptoki || true +- test -f $(DESTDIR)$(sysconfdir)/opencryptoki/p11sak_defined_attrs.conf || $(INSTALL) -g $(pkcs_group) -m 0640 $(srcdir)/usr/sbin/p11sak/p11sak_defined_attrs.conf $(DESTDIR)$(sysconfdir)/opencryptoki/p11sak_defined_attrs.conf || true ++ test -f $(DESTDIR)$(sysconfdir)/opencryptoki/p11sak_defined_attrs.conf || $(INSTALL) -m 0640 $(srcdir)/usr/sbin/p11sak/p11sak_defined_attrs.conf $(DESTDIR)$(sysconfdir)/opencryptoki/p11sak_defined_attrs.conf || true + endif + if ENABLE_ICATOK + cd $(DESTDIR)$(libdir)/opencryptoki/stdll && \ +@@ -151,7 +144,7 @@ endif + if ENABLE_DAEMON + test -f $(DESTDIR)$(sysconfdir)/opencryptoki || $(MKDIR_P) $(DESTDIR)$(sysconfdir)/opencryptoki || true + test -f $(DESTDIR)$(sysconfdir)/opencryptoki/opencryptoki.conf || $(INSTALL) -m 644 $(srcdir)/usr/sbin/pkcsslotd/opencryptoki.conf $(DESTDIR)$(sysconfdir)/opencryptoki/opencryptoki.conf || true +- test -f $(DESTDIR)$(sysconfdir)/opencryptoki/strength.conf || $(INSTALL) -m 640 -o root -g $(pkcs_group) -T $(srcdir)/doc/strength-example.conf $(DESTDIR)$(sysconfdir)/opencryptoki/strength.conf || true ++ test -f $(DESTDIR)$(sysconfdir)/opencryptoki/strength.conf || $(INSTALL) -m 640 -o root -T $(srcdir)/doc/strength-example.conf $(DESTDIR)$(sysconfdir)/opencryptoki/strength.conf || true + endif + $(MKDIR_P) $(DESTDIR)/etc/ld.so.conf.d + echo "$(libdir)/opencryptoki" >\ diff --git a/SOURCES/opencryptoki-CVE-2024-0914-part1.patch b/SOURCES/opencryptoki-CVE-2024-0914-part1.patch new file mode 100644 index 0000000..b4a68c4 --- /dev/null +++ b/SOURCES/opencryptoki-CVE-2024-0914-part1.patch @@ -0,0 +1,153 @@ +commit f931d6e47bf2fb26aa9cf52e231d13edc1c837a1 +Author: Ingo Franzki +Date: Tue Dec 12 17:16:56 2023 +0100 + + COMMON: Update rsa_parse_block_type_2() to not leak the message length + + Take the implementation of OpenSSL function RSA_padding_check_PKCS1_type_2() + in crypto/rsa/rsa_pk1.c instead of ossl_rsa_padding_check_PKCS1_type_2(), since + the latter leaks the message size. + + Signed-off-by: Ingo Franzki + +diff --git a/usr/lib/common/mech_rsa.c b/usr/lib/common/mech_rsa.c +index 326c5795..7bab1a84 100644 +--- a/usr/lib/common/mech_rsa.c ++++ b/usr/lib/common/mech_rsa.c +@@ -29,6 +29,7 @@ + #include "constant_time.h" + + #include ++#include + + CK_BBOOL is_rsa_mechanism(CK_MECHANISM_TYPE mech) + { +@@ -293,13 +294,16 @@ static CK_RV rsa_parse_block_type_2(CK_BYTE *in_data, + CK_BYTE *out_data, + CK_ULONG *out_data_len) + { +- unsigned int ok = 0, found, zero; +- size_t zero_index = 0, msg_index, mlen; +- size_t i, j; ++ int i; ++ unsigned char *em = NULL; ++ unsigned int good, found_zero_byte, mask, equals0; ++ int zero_index = 0, msg_index, mlen = -1; ++ int out_len = *out_data_len; ++ int rsa_size = in_data_len; + + /* + * The implementation of this function is copied from OpenSSL's function +- * ossl_rsa_padding_check_PKCS1_type_2() in crypto/rsa/rsa_pk1.c ++ * RSA_padding_check_PKCS1_type_2() in crypto/rsa/rsa_pk1.c + * and is slightly modified to fit to the OpenCryptoki environment. + * + * The OpenSSL code is licensed under the Apache License 2.0. +@@ -324,55 +328,86 @@ static CK_RV rsa_parse_block_type_2(CK_BYTE *in_data, + * PKCS#1 v1.5 decryption. See "PKCS #1 v2.2: RSA Cryptography Standard", + * section 7.2.2. + */ +- if (in_data_len < 11) { ++ if (rsa_size < RSA_PKCS1_PADDING_SIZE) { + TRACE_DEVEL("%s\n", ock_err(ERR_FUNCTION_FAILED)); + return CKR_FUNCTION_FAILED; + } + +- ok = constant_time_is_zero(in_data[0]); +- ok &= constant_time_eq(in_data[1], 2); ++ em = malloc(rsa_size); ++ if (em == NULL) { ++ TRACE_DEVEL("%s\n", ock_err(ERR_HOST_MEMORY)); ++ return CKR_HOST_MEMORY; ++ } ++ ++ /* in_data_len is always equal to rsa_size */ ++ memcpy(em, in_data, rsa_size); ++ ++ good = constant_time_is_zero(em[0]); ++ good &= constant_time_eq(em[1], 2); + + /* scan over padding data */ +- found = 0; +- for (i = 2; i < in_data_len; i++) { +- zero = constant_time_is_zero(in_data[i]); ++ found_zero_byte = 0; ++ for (i = 2; i < rsa_size; i++) { ++ equals0 = constant_time_is_zero(em[i]); + +- zero_index = constant_time_select_int(~found & zero, i, zero_index); +- found |= zero; ++ zero_index = constant_time_select_int(~found_zero_byte & equals0, ++ i, zero_index); ++ found_zero_byte |= equals0; + } + + /* +- * PS must be at least 8 bytes long, and it starts two bytes into |enc_msg|. ++ * PS must be at least 8 bytes long, and it starts two bytes into |em|. + * If we never found a 0-byte, then |zero_index| is 0 and the check + * also fails. + */ +- ok &= constant_time_ge(zero_index, 2 + 8); ++ good &= constant_time_ge(zero_index, 2 + 8); + + /* + * Skip the zero byte. This is incorrect if we never found a zero-byte + * but in this case we also do not copy the message out. + */ + msg_index = zero_index + 1; +- mlen = in_data_len - msg_index; ++ mlen = rsa_size - msg_index; + + /* + * For good measure, do this check in constant time as well. + */ +- ok &= constant_time_ge(*out_data_len, mlen); ++ good &= constant_time_ge(out_len, mlen); + + /* +- * since at this point the |msg_index| does not provide the signal +- * indicating if the padding check failed or not, we don't have to worry +- * about leaking the length of returned message, we still need to ensure +- * that we read contents of both buffers so that cache accesses don't leak +- * the value of |good| ++ * Move the result in-place by |rsa_size|-RSA_PKCS1_PADDING_SIZE-|mlen| ++ * bytes to the left. ++ * Then if |good| move |mlen| bytes from |em|+RSA_PKCS1_PADDING_SIZE to ++ * |out_data|. Otherwise leave |out_data| unchanged. ++ * Copy the memory back in a way that does not reveal the size of ++ * the data being copied via a timing side channel. This requires copying ++ * parts of the buffer multiple times based on the bits set in the real ++ * length. Clear bits do a non-copy with identical access pattern. ++ * The loop below has overall complexity of O(N*log(N)). + */ +- for (i = msg_index, j = 0; i < in_data_len && j < *out_data_len; i++, j++) +- out_data[j] = constant_time_select_8(ok, in_data[i], out_data[j]); ++ out_len = constant_time_select_int( ++ constant_time_lt(rsa_size - RSA_PKCS1_PADDING_SIZE, out_len), ++ rsa_size - RSA_PKCS1_PADDING_SIZE, ++ out_len); ++ for (msg_index = 1; msg_index < rsa_size - RSA_PKCS1_PADDING_SIZE; ++ msg_index <<= 1) { ++ mask = ~constant_time_eq( ++ msg_index & (rsa_size - RSA_PKCS1_PADDING_SIZE - mlen), 0); ++ for (i = RSA_PKCS1_PADDING_SIZE; i < rsa_size - msg_index; i++) ++ em[i] = constant_time_select_8(mask, em[i + msg_index], em[i]); ++ } ++ for (i = 0; i < out_len; i++) { ++ mask = good & constant_time_lt(i, mlen); ++ out_data[i] = constant_time_select_8( ++ mask, em[i + RSA_PKCS1_PADDING_SIZE], out_data[i]); ++ } ++ ++ OPENSSL_cleanse(em, rsa_size); ++ free(em); + +- *out_data_len = j; ++ *out_data_len = constant_time_select_int(good, mlen, 0); + +- return constant_time_select_int(ok, CKR_OK, CKR_ENCRYPTED_DATA_INVALID); ++ return constant_time_select_int(good, CKR_OK, CKR_ENCRYPTED_DATA_INVALID); + } + + CK_RV rsa_parse_block(CK_BYTE *in_data, diff --git a/SOURCES/opencryptoki-CVE-2024-0914-part2.patch b/SOURCES/opencryptoki-CVE-2024-0914-part2.patch new file mode 100644 index 0000000..69f3b55 --- /dev/null +++ b/SOURCES/opencryptoki-CVE-2024-0914-part2.patch @@ -0,0 +1,737 @@ +commit 5f1a4f8641306ee192b70c8a32c9ee8a0fe9be5f +Author: Ingo Franzki +Date: Mon Jan 15 12:53:37 2024 +0100 + + common: Add support for implicit rejection for RSA PKCS#1 v1.5 de-padding + + Implicit rejection returns a pseudo random message in case the RSA PKCS#1 v1.5 + padding is incorrect, but returns no error. The pseudo random message is based + on static secret data (the private exponent) and the provided ciphertext, so + that the attacker cannot determine that the returned value is randomly generated + instead of the result of decryption and de-padding. + + The implicit rejection algorithm is the same as used by OpenSSL. + + Signed-off-by: Ingo Franzki + +diff --git a/COPYRIGHTS b/COPYRIGHTS +index 2bb3dffe..21b6b702 100644 +--- a/COPYRIGHTS ++++ b/COPYRIGHTS +@@ -12,19 +12,29 @@ For code originating from OpenSSL: + * Note that in OpenSSL the file crypto/bn/rsa_sup_mul.c does no longer + * exist, it was removed with commit https://github.com/openssl/openssl/commit/4209ce68d8fe8b1506494efa03d378d05baf9ff8 + * - usr/lib/common/constant_time.h: Copied unchanged from OpenSSL from +- include/internal/constant_time.h ++ * include/internal/constant_time.h + * - The implementation of function rsa_parse_block_type_2() in + * usr/lib/common/mech_rsa.c is copied from OpenSSL's function + * ossl_rsa_padding_check_PKCS1_type_2() in crypto/rsa/rsa_pk1.c + * and is slightly modified to fit to the OpenCryptoki environment. + * See comment in function rsa_parse_block_type_2() for a list of changes. ++ * - The implementation of function openssl_specific_rsa_derive_kdk() in ++ * usr/lib/common/mech_openssl.c is copied from OpenSSL's function ++ * derive_kdk() in crypto/rsa/rsa_ossl.c and is slightly modified to fit to ++ * the OpenCryptoki environment. See comment in function ++ * openssl_specific_rsa_derive_kdk() for a list of changes. ++ * - The implementation of function openssl_specific_rsa_prf() in ++ * usr/lib/common/mech_openssl.c is copied from OpenSSL's function ++ * ossl_rsa_prf() in crypto/rsa/rsapk1.c and is slightly modified to fit to ++ * the OpenCryptoki environment. See comment in function ++ * openssl_specific_rsa_prf() for a list of changes. + * - The implementation of function decode_eme_oaep() in + * usr/lib/common/mech_rsa.c is copied from OpenSSL's function + * RSA_padding_check_PKCS1_OAEP_mgf1() in crypto/rsa/rsa_oaep.c and is + * slightly modified to fit to the OpenCryptoki environment. See comment in + * function decode_eme_oaep() for a list of changes. + * +- * Copyright 1999-2023 The OpenSSL Project Authors. All Rights Reserved. ++ * Copyright 1999-2024 The OpenSSL Project Authors. All Rights Reserved. + * + * The OpenSSL code is licensed under the Apache License 2.0 (the "License"). + * You can obtain a copy in the file LICENSE in the OpenSSL source distribution +diff --git a/usr/lib/common/h_extern.h b/usr/lib/common/h_extern.h +index a88b57d0..29496d99 100644 +--- a/usr/lib/common/h_extern.h ++++ b/usr/lib/common/h_extern.h +@@ -731,7 +731,8 @@ CK_RV rsa_format_block(STDLL_TokData_t *tokdata, + CK_RV rsa_parse_block(CK_BYTE *in_data, + CK_ULONG in_data_len, + CK_BYTE *out_data, +- CK_ULONG *out_data_len, CK_ULONG type); ++ CK_ULONG *out_data_len, CK_ULONG type, ++ CK_BYTE *kdk, CK_ULONG kdklen); + + CK_RV get_mgf_mech(CK_RSA_PKCS_MGF_TYPE mgf, CK_MECHANISM_TYPE *mech); + +@@ -3179,6 +3180,14 @@ CK_RV openssl_specific_hmac_update(SIGN_VERIFY_CONTEXT *ctx, CK_BYTE *in_data, + CK_RV openssl_specific_hmac_final(SIGN_VERIFY_CONTEXT *ctx, CK_BYTE *signature, + CK_ULONG *sig_len, CK_BBOOL sign); + ++CK_RV openssl_specific_rsa_derive_kdk(STDLL_TokData_t *tokdata, OBJECT *key_obj, ++ const CK_BYTE *in, CK_ULONG inlen, ++ CK_BYTE *kdk, CK_ULONG kdklen); ++CK_RV openssl_specific_rsa_prf(CK_BYTE *out, CK_ULONG outlen, ++ const char *label, CK_ULONG labellen, ++ const CK_BYTE *kdk, CK_ULONG kdklen, ++ uint16_t bitlen); ++ + #include "tok_spec_struct.h" + extern token_spec_t token_specific; + +diff --git a/usr/lib/common/mech_openssl.c b/usr/lib/common/mech_openssl.c +index 9983fcb3..da515289 100644 +--- a/usr/lib/common/mech_openssl.c ++++ b/usr/lib/common/mech_openssl.c +@@ -1154,6 +1154,7 @@ CK_RV openssl_specific_rsa_pkcs_decrypt(STDLL_TokData_t *tokdata, + CK_RV rc; + CK_BYTE out[MAX_RSA_KEYLEN]; + CK_ULONG modulus_bytes; ++ unsigned char kdk[SHA256_HASH_SIZE] = { 0 }; + + modulus_bytes = in_data_len; + +@@ -1163,7 +1164,16 @@ CK_RV openssl_specific_rsa_pkcs_decrypt(STDLL_TokData_t *tokdata, + goto done; + } + +- rc = rsa_parse_block(out, modulus_bytes, out_data, out_data_len, PKCS_BT_2); ++ rc = openssl_specific_rsa_derive_kdk(tokdata, key_obj, ++ in_data, in_data_len, ++ kdk, sizeof(kdk)); ++ if (rc != CKR_OK) { ++ TRACE_DEVEL("openssl_specific_rsa_derive_kdk failed\n"); ++ goto done; ++ } ++ ++ rc = rsa_parse_block(out, modulus_bytes, out_data, out_data_len, PKCS_BT_2, ++ kdk, sizeof(kdk)); + + done: + OPENSSL_cleanse(out, sizeof(out)); +@@ -1254,7 +1264,7 @@ CK_RV openssl_specific_rsa_pkcs_verify(STDLL_TokData_t *tokdata, SESSION *sess, + } + + rc = rsa_parse_block(out, modulus_bytes, out_data, &out_data_len, +- PKCS_BT_1); ++ PKCS_BT_1, NULL, 0); + if (rc == CKR_ENCRYPTED_DATA_INVALID) { + TRACE_ERROR("%s\n", ock_err(ERR_SIGNATURE_INVALID)); + return CKR_SIGNATURE_INVALID; +@@ -1318,7 +1328,8 @@ CK_RV openssl_specific_rsa_pkcs_verify_recover(STDLL_TokData_t *tokdata, + return rc; + } + +- rc = rsa_parse_block(out, modulus_bytes, out_data, out_data_len, PKCS_BT_1); ++ rc = rsa_parse_block(out, modulus_bytes, out_data, out_data_len, PKCS_BT_1, ++ NULL, 0); + if (rc == CKR_ENCRYPTED_DATA_INVALID) { + TRACE_ERROR("%s\n", ock_err(ERR_SIGNATURE_INVALID)); + return CKR_SIGNATURE_INVALID; +@@ -4983,3 +4994,388 @@ done: + ctx->context = NULL; + return rv; + } ++ ++static CK_RV calc_rsa_priv_exp(STDLL_TokData_t *tokdata, OBJECT *key_obj, ++ CK_BYTE *priv_exp, CK_ULONG priv_exp_len) ++{ ++ CK_ATTRIBUTE *modulus = NULL, *pub_exp = NULL; ++ CK_ATTRIBUTE *prime1 = NULL, *prime2 = NULL; ++ BN_CTX *bn_ctx; ++ BIGNUM *n, *e, *p, *q, *d; ++ CK_RV rc; ++ ++ UNUSED(tokdata); ++ ++ bn_ctx = BN_CTX_secure_new(); ++ if (bn_ctx == NULL) { ++ TRACE_ERROR("BN_CTX_secure_new failed\n"); ++ return CKR_FUNCTION_FAILED; ++ } ++ ++ /* Get modulus a BIGNUM */ ++ rc = template_attribute_get_non_empty(key_obj->template, CKA_MODULUS, ++ &modulus); ++ if (rc != CKR_OK) { ++ TRACE_ERROR("Failed to get CKA_MODULUS\n"); ++ goto done; ++ } ++ ++ n = BN_CTX_get(bn_ctx); ++ if (n == NULL || ++ BN_bin2bn(modulus->pValue, modulus->ulValueLen, n) == NULL) { ++ TRACE_ERROR("BN_CTX_get/BN_bin2bn failed for modulus\n"); ++ rc = CKR_FUNCTION_FAILED; ++ goto done; ++ } ++ BN_set_flags(n, BN_FLG_CONSTTIME); ++ ++ /* Get public exponent a BIGNUM */ ++ rc = template_attribute_get_non_empty(key_obj->template, ++ CKA_PUBLIC_EXPONENT, &pub_exp); ++ if (rc != CKR_OK) { ++ TRACE_ERROR("Failed to get CKA_PUBLIC_EXPONENT\n"); ++ goto done; ++ } ++ ++ e = BN_CTX_get(bn_ctx); ++ if (e == NULL || ++ BN_bin2bn(pub_exp->pValue, pub_exp->ulValueLen, e) == NULL) { ++ TRACE_ERROR("BN_CTX_get/BN_bin2bn failed for public exponent\n"); ++ rc = CKR_FUNCTION_FAILED; ++ goto done; ++ } ++ BN_set_flags(e, BN_FLG_CONSTTIME); ++ ++ /* Get prime1 a BIGNUM */ ++ rc = template_attribute_get_non_empty(key_obj->template, CKA_PRIME_1, ++ &prime1); ++ if (rc != CKR_OK) { ++ TRACE_ERROR("Failed to get CKA_PRIME_1\n"); ++ goto done; ++ } ++ ++ p = BN_CTX_get(bn_ctx); ++ if (p == NULL || ++ BN_bin2bn(prime1->pValue, prime1->ulValueLen, p) == NULL) { ++ TRACE_ERROR("BN_CTX_get/BN_bin2bn failed for prime1\n"); ++ rc = CKR_FUNCTION_FAILED; ++ goto done; ++ } ++ BN_set_flags(p, BN_FLG_CONSTTIME); ++ ++ /* Get prime2 a BIGNUM */ ++ rc = template_attribute_get_non_empty(key_obj->template, CKA_PRIME_2, ++ &prime2); ++ if (rc != CKR_OK) { ++ TRACE_ERROR("Failed to get CKA_PRIME_2\n"); ++ goto done; ++ } ++ ++ q = BN_CTX_get(bn_ctx); ++ if (q == NULL || ++ BN_bin2bn(prime2->pValue, prime2->ulValueLen, q) == NULL) { ++ TRACE_ERROR("BN_CTX_get/BN_bin2bn failed for prime2\n"); ++ rc = CKR_FUNCTION_FAILED; ++ goto done; ++ } ++ BN_set_flags(q, BN_FLG_CONSTTIME); ++ ++ d = BN_CTX_get(bn_ctx); ++ if (d == NULL) { ++ TRACE_ERROR("BN_CTX_get failed to get d\n"); ++ rc = CKR_FUNCTION_FAILED; ++ goto done; ++ } ++ BN_set_flags(d, BN_FLG_CONSTTIME); ++ ++ /* ++ * phi(n) = (p - 1 )(q - 1) = n - p - q + 1 ++ * d = e ^{-1} mod phi(n). ++ */ ++ if (BN_copy(d, n) == NULL || ++ BN_sub(d, d, p) == 0 || ++ BN_sub(d, d, q) == 0 || ++ BN_add_word(d, 1) == 0 || ++ BN_mod_inverse(d, e, d, bn_ctx) == NULL) { ++ TRACE_ERROR("Failed to calculate private key part d\n"); ++ rc = CKR_FUNCTION_FAILED; ++ goto done; ++ } ++ ++ if (BN_bn2binpad(d, priv_exp, priv_exp_len) <= 0) { ++ TRACE_ERROR("BN_bn2binpad failed\n"); ++ rc = CKR_FUNCTION_FAILED; ++ goto done; ++ } ++ ++done: ++ BN_CTX_free(bn_ctx); ++ ++ return rc; ++} ++ ++CK_RV openssl_specific_rsa_derive_kdk(STDLL_TokData_t *tokdata, OBJECT *key_obj, ++ const CK_BYTE *in, CK_ULONG inlen, ++ CK_BYTE *kdk, CK_ULONG kdklen) ++{ ++ CK_ATTRIBUTE *priv_exp_attr = NULL, *modulus = NULL; ++ CK_BYTE *priv_exp = NULL, *buf = NULL; ++ EVP_PKEY *pkey = NULL; ++ EVP_MD_CTX *mdctx = NULL; ++ const EVP_MD *md = NULL; ++ size_t md_len; ++ unsigned char d_hash[SHA256_HASH_SIZE] = { 0 }; ++ CK_RV rc; ++ ++ /* ++ * The implementation of this function is copied from OpenSSL's function ++ * derive_kdk() in crypto/rsa/rsa_ossl.c and is slightly modified to fit to ++ * the OpenCryptoki environment. ++ * Changes include: ++ * - Different variable and define names. ++ * - Usage of TRACE_ERROR to report errors and issue debug messages. ++ * - Different return codes. ++ * - Different code to get the private key component 'd'. ++ * - Use of the EVP APIs instead of the internal APIs for Digest and HMAC ++ * operations. ++ */ ++ ++ if (kdklen != SHA256_HASH_SIZE) { ++ TRACE_ERROR("KDK length is wrong\n"); ++ return CKR_ARGUMENTS_BAD; ++ } ++ ++ rc = template_attribute_get_non_empty(key_obj->template, CKA_MODULUS, ++ &modulus); ++ if (rc != CKR_OK) { ++ TRACE_ERROR("Failed to get CKA_MODULUS\n"); ++ return rc; ++ } ++ ++ buf = calloc(1, modulus->ulValueLen); ++ if (buf == NULL) { ++ TRACE_ERROR("Failed to allocate a buffer for private exponent\n"); ++ return CKR_HOST_MEMORY; ++ } ++ ++ rc = template_attribute_get_non_empty(key_obj->template, ++ CKA_PRIVATE_EXPONENT, &priv_exp_attr); ++ if (rc != CKR_OK && rc != CKR_TEMPLATE_INCOMPLETE) { ++ TRACE_ERROR("Failed to get CKA_PRIVATE_EXPONENT\n"); ++ goto out; ++ } ++ ++ if (priv_exp_attr == NULL) { ++ rc = calc_rsa_priv_exp(tokdata, key_obj, buf, modulus->ulValueLen); ++ if (rc != CKR_OK) { ++ TRACE_ERROR("calc_rsa_priv_exp failed\n"); ++ goto out; ++ } ++ priv_exp = buf; ++ } else { ++ if (priv_exp_attr->ulValueLen < modulus->ulValueLen) { ++ memcpy(buf + modulus->ulValueLen - priv_exp_attr->ulValueLen, ++ priv_exp_attr->pValue, priv_exp_attr->ulValueLen); ++ priv_exp = buf; ++ } else { ++ priv_exp = (CK_BYTE *)priv_exp_attr->pValue + ++ priv_exp_attr->ulValueLen - modulus->ulValueLen; ++ } ++ } ++ ++ /* ++ * we use hardcoded hash so that migrating between versions that use ++ * different hash doesn't provide a Bleichenbacher oracle: ++ * if the attacker can see that different versions return different ++ * messages for the same ciphertext, they'll know that the message is ++ * synthetically generated, which means that the padding check failed ++ */ ++ md = EVP_sha256(); ++ if (md == NULL) { ++ TRACE_ERROR("EVP_sha256 failed\n"); ++ rc = CKR_FUNCTION_FAILED; ++ goto out; ++ } ++ ++ if (EVP_Digest(priv_exp, modulus->ulValueLen, d_hash, NULL, ++ md, NULL) <= 0) { ++ TRACE_ERROR("EVP_Digest failed\n"); ++ rc = CKR_FUNCTION_FAILED; ++ goto out; ++ } ++ ++ pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, d_hash, sizeof(d_hash)); ++ if (pkey == NULL) { ++ TRACE_ERROR("EVP_PKEY_new_mac_key() failed.\n"); ++ rc = CKR_FUNCTION_FAILED; ++ goto out; ++ } ++ ++ mdctx = EVP_MD_CTX_create(); ++ if (mdctx == NULL) { ++ TRACE_ERROR("EVP_MD_CTX_create() failed.\n"); ++ rc = CKR_FUNCTION_FAILED; ++ goto out; ++ } ++ ++ if (EVP_DigestSignInit(mdctx, NULL, md, NULL, pkey) != 1) { ++ TRACE_ERROR("EVP_DigestSignInit failed\n"); ++ rc = CKR_FUNCTION_FAILED; ++ goto out; ++ } ++ ++ if (inlen < modulus->ulValueLen) { ++ memset(buf, 0, modulus->ulValueLen - inlen); ++ if (EVP_DigestSignUpdate(mdctx, buf, modulus->ulValueLen - inlen)!= 1) { ++ TRACE_ERROR("EVP_DigestSignUpdate failed\n"); ++ rc = CKR_FUNCTION_FAILED; ++ goto out; ++ } ++ } ++ if (EVP_DigestSignUpdate(mdctx, in, inlen) != 1) { ++ TRACE_ERROR("EVP_DigestSignUpdate failed\n"); ++ rc = CKR_FUNCTION_FAILED; ++ goto out; ++ } ++ ++ md_len = kdklen; ++ if (EVP_DigestSignFinal(mdctx, kdk, &md_len) != 1 || ++ md_len != kdklen) { ++ TRACE_ERROR("EVP_DigestSignFinal failed\n"); ++ rc = CKR_FUNCTION_FAILED; ++ goto out; ++ } ++ ++ rc = CKR_OK; ++ ++out: ++ if (buf != NULL) ++ free(buf); ++ if (pkey != NULL) ++ EVP_PKEY_free(pkey); ++ if (mdctx != NULL) ++ EVP_MD_CTX_free(mdctx); ++ ++ return rc; ++} ++ ++CK_RV openssl_specific_rsa_prf(CK_BYTE *out, CK_ULONG outlen, ++ const char *label, CK_ULONG labellen, ++ const CK_BYTE *kdk, CK_ULONG kdklen, ++ uint16_t bitlen) ++{ ++ CK_RV rc; ++ CK_ULONG pos; ++ uint16_t iter = 0; ++ unsigned char be_iter[sizeof(iter)]; ++ unsigned char be_bitlen[sizeof(bitlen)]; ++ EVP_PKEY *pkey = NULL; ++ EVP_MD_CTX *mdctx = NULL; ++ unsigned char hmac_out[SHA256_HASH_SIZE]; ++ size_t md_len; ++ ++ /* ++ * The implementation of this function is copied from OpenSSL's function ++ * ossl_rsa_prf() in crypto/rsa/rsapk1.c and is slightly modified to fit to ++ * the providers environment. ++ * Changes include: ++ * - Different variable and define names. ++ * - Usage of TRACE_ERROR report errors and issue debug messages. ++ * - Different return codes. ++ * - Use of the EVP API instead of the internal APIs for HMAC operations. ++ */ ++ ++ if (kdklen != SHA256_HASH_SIZE) { ++ TRACE_ERROR("invalid kdklen\n"); ++ return CKR_ARGUMENTS_BAD; ++ } ++ if (outlen * 8 != bitlen) { ++ TRACE_ERROR("invalid outlen\n"); ++ return CKR_ARGUMENTS_BAD; ++ } ++ ++ be_bitlen[0] = (bitlen >> 8) & 0xff; ++ be_bitlen[1] = bitlen & 0xff; ++ ++ pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, kdk, kdklen); ++ if (pkey == NULL) { ++ TRACE_ERROR("EVP_PKEY_new_mac_key() failed.\n"); ++ rc = CKR_FUNCTION_FAILED; ++ goto out; ++ } ++ ++ mdctx = EVP_MD_CTX_create(); ++ if (mdctx == NULL) { ++ TRACE_ERROR("EVP_MD_CTX_create() failed.\n"); ++ rc = CKR_FUNCTION_FAILED; ++ goto out; ++ } ++ ++ /* ++ * we use hardcoded hash so that migrating between versions that use ++ * different hash doesn't provide a Bleichenbacher oracle: ++ * if the attacker can see that different versions return different ++ * messages for the same ciphertext, they'll know that the message is ++ * synthetically generated, which means that the padding check failed ++ */ ++ for (pos = 0; pos < outlen; pos += SHA256_HASH_SIZE, iter++) { ++ if (EVP_DigestSignInit(mdctx, NULL, EVP_sha256(), NULL, pkey) != 1) { ++ TRACE_ERROR("EVP_DigestSignInit failed\n"); ++ rc = CKR_FUNCTION_FAILED; ++ goto out; ++ } ++ ++ be_iter[0] = (iter >> 8) & 0xff; ++ be_iter[1] = iter & 0xff; ++ ++ if (EVP_DigestSignUpdate(mdctx, be_iter, sizeof(be_iter)) != 1) { ++ TRACE_ERROR("EVP_DigestSignUpdate failed\n"); ++ rc = CKR_FUNCTION_FAILED; ++ goto out; ++ } ++ if (EVP_DigestSignUpdate(mdctx, (unsigned char *)label, labellen) != 1) { ++ TRACE_ERROR("EVP_DigestSignUpdate failed\n"); ++ rc = CKR_FUNCTION_FAILED; ++ goto out; ++ } ++ if (EVP_DigestSignUpdate(mdctx, be_bitlen, sizeof(be_bitlen)) != 1) { ++ TRACE_ERROR("EVP_DigestSignUpdate failed\n"); ++ rc = CKR_FUNCTION_FAILED; ++ goto out; ++ } ++ ++ /* ++ * HMAC_Final requires the output buffer to fit the whole MAC ++ * value, so we need to use the intermediate buffer for the last ++ * unaligned block ++ */ ++ md_len = SHA256_HASH_SIZE; ++ if (pos + SHA256_HASH_SIZE > outlen) { ++ md_len = sizeof(hmac_out); ++ if (EVP_DigestSignFinal(mdctx, hmac_out, &md_len) != 1) { ++ TRACE_ERROR("EVP_DigestSignFinal failed\n"); ++ rc = CKR_FUNCTION_FAILED; ++ goto out; ++ } ++ memcpy(out + pos, hmac_out, outlen - pos); ++ } else { ++ md_len = outlen - pos; ++ if (EVP_DigestSignFinal(mdctx, out + pos, &md_len) != 1) { ++ TRACE_ERROR("EVP_DigestSignFinal failed\n"); ++ rc = CKR_FUNCTION_FAILED; ++ goto out; ++ } ++ } ++ } ++ ++ rc = CKR_OK; ++ ++out: ++ if (pkey != NULL) ++ EVP_PKEY_free(pkey); ++ if (mdctx != NULL) ++ EVP_MD_CTX_free(mdctx); ++ ++ return rc; ++} ++ +diff --git a/usr/lib/common/mech_rsa.c b/usr/lib/common/mech_rsa.c +index 7bab1a84..7dc9589a 100644 +--- a/usr/lib/common/mech_rsa.c ++++ b/usr/lib/common/mech_rsa.c +@@ -289,21 +289,34 @@ static CK_RV rsa_parse_block_type_1(CK_BYTE *in_data, + return rc; + } + ++#define MAX_LEN_GEN_TRIES 128 ++ + static CK_RV rsa_parse_block_type_2(CK_BYTE *in_data, + CK_ULONG in_data_len, + CK_BYTE *out_data, +- CK_ULONG *out_data_len) ++ CK_ULONG *out_data_len, ++ CK_BYTE *kdk, CK_ULONG kdklen) + { +- int i; +- unsigned char *em = NULL; +- unsigned int good, found_zero_byte, mask, equals0; +- int zero_index = 0, msg_index, mlen = -1; +- int out_len = *out_data_len; +- int rsa_size = in_data_len; ++ unsigned int good = 0, found_zero_byte, equals0; ++ size_t zero_index = 0, msg_index; ++ unsigned char *synthetic = NULL; ++ int synthetic_length; ++ uint16_t len_candidate; ++ unsigned char candidate_lengths[MAX_LEN_GEN_TRIES * sizeof(len_candidate)]; ++ uint16_t len_mask; ++ uint16_t max_sep_offset; ++ int synth_msg_index = 0; ++ size_t i, j; ++ CK_RV rc; ++ ++ if (kdk == NULL || kdklen == 0) { ++ TRACE_DEVEL("%s\n", ock_err(ERR_ARGUMENTS_BAD)); ++ return CKR_ARGUMENTS_BAD; ++ } + + /* + * The implementation of this function is copied from OpenSSL's function +- * RSA_padding_check_PKCS1_type_2() in crypto/rsa/rsa_pk1.c ++ * ossl_rsa_padding_check_PKCS1_type_2() in crypto/rsa/rsa_pk1.c + * and is slightly modified to fit to the OpenCryptoki environment. + * + * The OpenSSL code is licensed under the Apache License 2.0. +@@ -328,27 +341,67 @@ static CK_RV rsa_parse_block_type_2(CK_BYTE *in_data, + * PKCS#1 v1.5 decryption. See "PKCS #1 v2.2: RSA Cryptography Standard", + * section 7.2.2. + */ +- if (rsa_size < RSA_PKCS1_PADDING_SIZE) { ++ if (in_data_len < RSA_PKCS1_PADDING_SIZE) { + TRACE_DEVEL("%s\n", ock_err(ERR_FUNCTION_FAILED)); + return CKR_FUNCTION_FAILED; + } + +- em = malloc(rsa_size); +- if (em == NULL) { +- TRACE_DEVEL("%s\n", ock_err(ERR_HOST_MEMORY)); ++ /* Generate a random message to return in case the padding checks fail. */ ++ synthetic = calloc(1, in_data_len); ++ if (synthetic == NULL) { ++ TRACE_ERROR("Failed to allocate synthetic buffer"); + return CKR_HOST_MEMORY; + } + +- /* in_data_len is always equal to rsa_size */ +- memcpy(em, in_data, rsa_size); ++ rc = openssl_specific_rsa_prf(synthetic, in_data_len, "message", 7, ++ kdk, kdklen, in_data_len * 8); ++ if (rc != CKR_OK) ++ goto out; ++ ++ /* decide how long the random message should be */ ++ rc = openssl_specific_rsa_prf(candidate_lengths, ++ sizeof(candidate_lengths), ++ "length", 6, kdk, kdklen, ++ MAX_LEN_GEN_TRIES * ++ sizeof(len_candidate) * 8); ++ if (rc != CKR_OK) ++ goto out; + +- good = constant_time_is_zero(em[0]); +- good &= constant_time_eq(em[1], 2); ++ /* ++ * max message size is the size of the modulus size minus 2 bytes for ++ * version and padding type and a minimum of 8 bytes padding ++ */ ++ len_mask = max_sep_offset = in_data_len - 2 - 8; ++ /* ++ * we want a mask so let's propagate the high bit to all positions less ++ * significant than it ++ */ ++ len_mask |= len_mask >> 1; ++ len_mask |= len_mask >> 2; ++ len_mask |= len_mask >> 4; ++ len_mask |= len_mask >> 8; ++ ++ synthetic_length = 0; ++ for (i = 0; i < MAX_LEN_GEN_TRIES * (int)sizeof(len_candidate); ++ i += sizeof(len_candidate)) { ++ len_candidate = (candidate_lengths[i] << 8) | ++ candidate_lengths[i + 1]; ++ len_candidate &= len_mask; ++ ++ synthetic_length = constant_time_select_int( ++ constant_time_lt(len_candidate, max_sep_offset), ++ len_candidate, synthetic_length); ++ } ++ ++ synth_msg_index = in_data_len - synthetic_length; ++ ++ good = constant_time_is_zero(in_data[0]); ++ good &= constant_time_eq(in_data[1], 2); + + /* scan over padding data */ + found_zero_byte = 0; +- for (i = 2; i < rsa_size; i++) { +- equals0 = constant_time_is_zero(em[i]); ++ for (i = 2; i < in_data_len; i++) { ++ equals0 = constant_time_is_zero(in_data[i]); + + zero_index = constant_time_select_int(~found_zero_byte & equals0, + i, zero_index); +@@ -356,7 +409,7 @@ static CK_RV rsa_parse_block_type_2(CK_BYTE *in_data, + } + + /* +- * PS must be at least 8 bytes long, and it starts two bytes into |em|. ++ * PS must be at least 8 bytes long, and it starts two bytes into |in_data|. + * If we never found a 0-byte, then |zero_index| is 0 and the check + * also fails. + */ +@@ -367,53 +420,41 @@ static CK_RV rsa_parse_block_type_2(CK_BYTE *in_data, + * but in this case we also do not copy the message out. + */ + msg_index = zero_index + 1; +- mlen = rsa_size - msg_index; + + /* +- * For good measure, do this check in constant time as well. ++ * old code returned an error in case the decrypted message wouldn't fit ++ * into the |out_data|, since that would leak information, return the ++ * synthetic message instead + */ +- good &= constant_time_ge(out_len, mlen); ++ good &= constant_time_ge(*out_data_len, in_data_len - msg_index); ++ ++ msg_index = constant_time_select_int(good, msg_index, synth_msg_index); + + /* +- * Move the result in-place by |rsa_size|-RSA_PKCS1_PADDING_SIZE-|mlen| +- * bytes to the left. +- * Then if |good| move |mlen| bytes from |em|+RSA_PKCS1_PADDING_SIZE to +- * |out_data|. Otherwise leave |out_data| unchanged. +- * Copy the memory back in a way that does not reveal the size of +- * the data being copied via a timing side channel. This requires copying +- * parts of the buffer multiple times based on the bits set in the real +- * length. Clear bits do a non-copy with identical access pattern. +- * The loop below has overall complexity of O(N*log(N)). ++ * since at this point the |msg_index| does not provide the signal ++ * indicating if the padding check failed or not, we don't have to worry ++ * about leaking the length of returned message, we still need to ensure ++ * that we read contents of both buffers so that cache accesses don't leak ++ * the value of |good| + */ +- out_len = constant_time_select_int( +- constant_time_lt(rsa_size - RSA_PKCS1_PADDING_SIZE, out_len), +- rsa_size - RSA_PKCS1_PADDING_SIZE, +- out_len); +- for (msg_index = 1; msg_index < rsa_size - RSA_PKCS1_PADDING_SIZE; +- msg_index <<= 1) { +- mask = ~constant_time_eq( +- msg_index & (rsa_size - RSA_PKCS1_PADDING_SIZE - mlen), 0); +- for (i = RSA_PKCS1_PADDING_SIZE; i < rsa_size - msg_index; i++) +- em[i] = constant_time_select_8(mask, em[i + msg_index], em[i]); +- } +- for (i = 0; i < out_len; i++) { +- mask = good & constant_time_lt(i, mlen); +- out_data[i] = constant_time_select_8( +- mask, em[i + RSA_PKCS1_PADDING_SIZE], out_data[i]); +- } ++ for (i = msg_index, j = 0; i < in_data_len && j < *out_data_len; ++ i++, j++) ++ out_data[j] = constant_time_select_8(good, in_data[i], synthetic[i]); + +- OPENSSL_cleanse(em, rsa_size); +- free(em); ++ *out_data_len = j; + +- *out_data_len = constant_time_select_int(good, mlen, 0); ++out: ++ if (synthetic != NULL) ++ free(synthetic); + +- return constant_time_select_int(good, CKR_OK, CKR_ENCRYPTED_DATA_INVALID); ++ return rc; + } + + CK_RV rsa_parse_block(CK_BYTE *in_data, + CK_ULONG in_data_len, + CK_BYTE *out_data, +- CK_ULONG *out_data_len, CK_ULONG type) ++ CK_ULONG *out_data_len, CK_ULONG type, ++ CK_BYTE *kdk, CK_ULONG kdklen) + { + switch (type) { + case PKCS_BT_1: +@@ -421,7 +462,7 @@ CK_RV rsa_parse_block(CK_BYTE *in_data, + out_data, out_data_len); + case PKCS_BT_2: + return rsa_parse_block_type_2(in_data, in_data_len, +- out_data, out_data_len); ++ out_data, out_data_len, kdk, kdklen); + } + + return CKR_ARGUMENTS_BAD; diff --git a/SOURCES/opencryptoki-CVE-2024-0914-part3.patch b/SOURCES/opencryptoki-CVE-2024-0914-part3.patch new file mode 100644 index 0000000..4994b73 --- /dev/null +++ b/SOURCES/opencryptoki-CVE-2024-0914-part3.patch @@ -0,0 +1,387 @@ +commit e2b496f58a84c2f537667655fe08a0d4923f0c70 +Author: Ingo Franzki +Date: Fri Jan 12 09:36:27 2024 +0100 + + Constant time fixes for C_Decrypt return code handling + + Return code handling of C_Decrypt, C_DecryptUpdate, and C_DecryptFinal must + be performed in a constant time manner for RSA mechanisms. Otherwise it + may cause a timing side channel that may be used to perform a Bleichenbacher + style attack. + + Handling of error situations with CKR_BUFFER_TOO_SMALL or size-query calls, + where the output buffer is NULL and the required size of the output buffer + is to be returned, do not need to be performed in constant time, since + these cases are shortcut anyway, and the result is only dependent on the + modulus size of the RSA key (which is public information anyway). + + Signed-off-by: Ingo Franzki + +diff --git a/usr/lib/common/new_host.c b/usr/lib/common/new_host.c +index 8a1e8723..bbb0f601 100644 +--- a/usr/lib/common/new_host.c ++++ b/usr/lib/common/new_host.c +@@ -47,6 +47,7 @@ + #include "trace.h" + #include "slotmgr.h" + #include "attributes.h" ++#include "constant_time.h" + + #include "../api/apiproto.h" + #include "../api/policy.h" +@@ -2345,6 +2346,7 @@ CK_RV SC_Decrypt(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession, + SESSION *sess = NULL; + CK_BBOOL length_only = FALSE; + CK_RV rc = CKR_OK; ++ unsigned int mask; + + if (tokdata->initialized == FALSE) { + TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); +@@ -2377,11 +2379,19 @@ CK_RV SC_Decrypt(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession, + rc = decr_mgr_decrypt(tokdata, sess, length_only, &sess->decr_ctx, + pEncryptedData, ulEncryptedDataLen, pData, + pulDataLen); +- if (!is_rsa_mechanism(sess->decr_ctx.mech.mechanism) && rc != CKR_OK) ++ /* (!is_rsa_mechanism(sess->decr_ctx.mech.mechanism) && rc != CKR_OK) */ ++ mask = ~constant_time_is_zero( ++ is_rsa_mechanism(sess->decr_ctx.mech.mechanism)); ++ mask &= ~constant_time_eq(rc, CKR_OK); ++ if (mask) + TRACE_DEVEL("decr_mgr_decrypt() failed.\n"); + + done: +- if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) { ++ /* (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) */ ++ mask = ~constant_time_eq(rc, CKR_OK); ++ mask |= constant_time_is_zero(length_only); ++ mask &= ~constant_time_eq(rc, CKR_BUFFER_TOO_SMALL); ++ if (mask) { + if (sess) + decr_mgr_cleanup(tokdata, sess, &sess->decr_ctx); + } +@@ -2404,6 +2414,7 @@ CK_RV SC_DecryptUpdate(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession, + SESSION *sess = NULL; + CK_BBOOL length_only = FALSE; + CK_RV rc = CKR_OK; ++ unsigned int mask; + + if (tokdata->initialized == FALSE) { + TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); +@@ -2436,11 +2447,18 @@ CK_RV SC_DecryptUpdate(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession, + rc = decr_mgr_decrypt_update(tokdata, sess, length_only, + &sess->decr_ctx, pEncryptedPart, + ulEncryptedPartLen, pPart, pulPartLen); +- if (!is_rsa_mechanism(sess->decr_ctx.mech.mechanism) && rc != CKR_OK) ++ /* (!is_rsa_mechanism(sess->decr_ctx.mech.mechanism) && rc != CKR_OK) */ ++ mask = ~constant_time_is_zero( ++ is_rsa_mechanism(sess->decr_ctx.mech.mechanism)); ++ mask &= ~constant_time_eq(rc, CKR_OK); ++ if (mask) + TRACE_DEVEL("decr_mgr_decrypt_update() failed.\n"); + + done: +- if (rc != CKR_OK && rc != CKR_BUFFER_TOO_SMALL && sess != NULL) { ++ /* (rc != CKR_OK && rc != CKR_BUFFER_TOO_SMALL */ ++ mask = ~constant_time_eq(rc, CKR_OK); ++ mask &= ~constant_time_eq(rc, CKR_BUFFER_TOO_SMALL); ++ if (mask) { + if (sess) + decr_mgr_cleanup(tokdata, sess, &sess->decr_ctx); + } +@@ -2462,6 +2480,7 @@ CK_RV SC_DecryptFinal(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession, + SESSION *sess = NULL; + CK_BBOOL length_only = FALSE; + CK_RV rc = CKR_OK; ++ unsigned int mask; + + if (tokdata->initialized == FALSE) { + TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); +@@ -2493,11 +2512,19 @@ CK_RV SC_DecryptFinal(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession, + + rc = decr_mgr_decrypt_final(tokdata, sess, length_only, &sess->decr_ctx, + pLastPart, pulLastPartLen); +- if (!is_rsa_mechanism(sess->decr_ctx.mech.mechanism) && rc != CKR_OK) ++ /* (!is_rsa_mechanism(sess->decr_ctx.mech.mechanism) && rc != CKR_OK) */ ++ mask = ~constant_time_is_zero( ++ is_rsa_mechanism(sess->decr_ctx.mech.mechanism)); ++ mask &= ~constant_time_eq(rc, CKR_OK); ++ if (mask) + TRACE_DEVEL("decr_mgr_decrypt_final() failed.\n"); + + done: +- if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) { ++ /* (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) */ ++ mask = ~constant_time_eq(rc, CKR_OK); ++ mask |= constant_time_is_zero(length_only); ++ mask &= ~constant_time_eq(rc, CKR_BUFFER_TOO_SMALL); ++ if (mask) { + if (sess) + decr_mgr_cleanup(tokdata, sess, &sess->decr_ctx); + } +diff --git a/usr/lib/ep11_stdll/ep11_specific.c b/usr/lib/ep11_stdll/ep11_specific.c +index 073b349f..6d08b95e 100644 +--- a/usr/lib/ep11_stdll/ep11_specific.c ++++ b/usr/lib/ep11_stdll/ep11_specific.c +@@ -9552,10 +9552,12 @@ CK_RV ep11tok_decrypt_final(STDLL_TokData_t * tokdata, SESSION * session, + rc = constant_time_select(constant_time_eq(rc, CKR_OK), + ep11_error_to_pkcs11_error(rc, session), + rc); +- if (rc != CKR_OK) { +- TRACE_ERROR("%s rc=0x%lx\n", __func__, rc); +- } else { +- TRACE_INFO("%s rc=0x%lx\n", __func__, rc); ++ if (!is_rsa_mechanism(ctx->mech.mechanism)) { ++ if (rc != CKR_OK) { ++ TRACE_ERROR("%s rc=0x%lx\n", __func__, rc); ++ } else { ++ TRACE_INFO("%s rc=0x%lx\n", __func__, rc); ++ } + } + + done: +@@ -9611,10 +9613,12 @@ CK_RV ep11tok_decrypt(STDLL_TokData_t * tokdata, SESSION * session, + rc = constant_time_select(constant_time_eq(rc, CKR_OK), + ep11_error_to_pkcs11_error(rc, session), + rc); +- if (rc != CKR_OK) { +- TRACE_ERROR("%s rc=0x%lx\n", __func__, rc); +- } else { +- TRACE_INFO("%s rc=0x%lx\n", __func__, rc); ++ if (!is_rsa_mechanism(ctx->mech.mechanism)) { ++ if (rc != CKR_OK) { ++ TRACE_ERROR("%s rc=0x%lx\n", __func__, rc); ++ } else { ++ TRACE_INFO("%s rc=0x%lx\n", __func__, rc); ++ } + } + + done: +@@ -9676,10 +9680,12 @@ CK_RV ep11tok_decrypt_update(STDLL_TokData_t * tokdata, SESSION * session, + rc = constant_time_select(constant_time_eq(rc, CKR_OK), + ep11_error_to_pkcs11_error(rc, session), + rc); +- if (rc != CKR_OK) { +- TRACE_ERROR("%s rc=0x%lx\n", __func__, rc); +- } else { +- TRACE_INFO("%s rc=0x%lx\n", __func__, rc); ++ if (!is_rsa_mechanism(ctx->mech.mechanism)) { ++ if (rc != CKR_OK) { ++ TRACE_ERROR("%s rc=0x%lx\n", __func__, rc); ++ } else { ++ TRACE_INFO("%s rc=0x%lx\n", __func__, rc); ++ } + } + + done: +diff --git a/usr/lib/ep11_stdll/new_host.c b/usr/lib/ep11_stdll/new_host.c +index 55e34c18..299a1d3c 100644 +--- a/usr/lib/ep11_stdll/new_host.c ++++ b/usr/lib/ep11_stdll/new_host.c +@@ -38,6 +38,7 @@ + #include "slotmgr.h" + #include "attributes.h" + #include "ep11_specific.h" ++#include "constant_time.h" + + #include "../api/apiproto.h" + #include "../api/policy.h" +@@ -2466,6 +2467,7 @@ CK_RV SC_Decrypt(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession, + SESSION *sess = NULL; + CK_BBOOL length_only = FALSE; + CK_RV rc = CKR_OK; ++ unsigned int mask; + + if (tokdata->initialized == FALSE) { + TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); +@@ -2513,17 +2515,29 @@ CK_RV SC_Decrypt(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession, + length_only, sess->decr_ctx.key, + pEncryptedData, ulEncryptedDataLen, + pData, pulDataLen); +- if (!is_rsa_mechanism(sess->decr_ctx.mech.mechanism) && rc != CKR_OK) ++ /* (!is_rsa_mechanism(sess->decr_ctx.mech.mechanism) && rc != CKR_OK) */ ++ mask = ~constant_time_is_zero( ++ is_rsa_mechanism(sess->decr_ctx.mech.mechanism)); ++ mask &= ~constant_time_eq(rc, CKR_OK); ++ if (mask) + TRACE_DEVEL("ep11tok_decrypt_single() failed.\n"); + } else { + rc = ep11tok_decrypt(tokdata, sess, pEncryptedData, ulEncryptedDataLen, + pData, pulDataLen); +- if (!is_rsa_mechanism(sess->decr_ctx.mech.mechanism) && rc != CKR_OK) ++ /* (!is_rsa_mechanism(sess->decr_ctx.mech.mechanism) && rc != CKR_OK) */ ++ mask = ~constant_time_is_zero( ++ is_rsa_mechanism(sess->decr_ctx.mech.mechanism)); ++ mask &= ~constant_time_eq(rc, CKR_OK); ++ if (mask) + TRACE_DEVEL("ep11tok_decrypt() failed.\n"); + } + + done: +- if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) { ++ /* (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) */ ++ mask = ~constant_time_eq(rc, CKR_OK); ++ mask |= constant_time_is_zero(length_only); ++ mask &= ~constant_time_eq(rc, CKR_BUFFER_TOO_SMALL); ++ if (mask) { + if (sess) + decr_mgr_cleanup(tokdata, sess, &sess->decr_ctx); + } +@@ -2545,6 +2559,7 @@ CK_RV SC_DecryptUpdate(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession, + { + SESSION *sess = NULL; + CK_RV rc = CKR_OK; ++ unsigned int mask; + + if (tokdata->initialized == FALSE) { + TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); +@@ -2596,11 +2611,18 @@ CK_RV SC_DecryptUpdate(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession, + + rc = ep11tok_decrypt_update(tokdata, sess, pEncryptedPart, + ulEncryptedPartLen, pPart, pulPartLen); +- if (!is_rsa_mechanism(sess->decr_ctx.mech.mechanism) && rc != CKR_OK) ++ /* (!is_rsa_mechanism(sess->decr_ctx.mech.mechanism) && rc != CKR_OK) */ ++ mask = ~constant_time_is_zero( ++ is_rsa_mechanism(sess->decr_ctx.mech.mechanism)); ++ mask &= ~constant_time_eq(rc, CKR_OK); ++ if (mask) + TRACE_DEVEL("ep11tok_decrypt_update() failed.\n"); + + done: +- if (rc != CKR_OK && rc != CKR_BUFFER_TOO_SMALL && sess != NULL) { ++ /* (rc != CKR_OK && rc != CKR_BUFFER_TOO_SMALL */ ++ mask = ~constant_time_eq(rc, CKR_OK); ++ mask &= ~constant_time_eq(rc, CKR_BUFFER_TOO_SMALL); ++ if (mask) { + if (sess) + decr_mgr_cleanup(tokdata, sess, &sess->decr_ctx); + } +@@ -2622,6 +2644,7 @@ CK_RV SC_DecryptFinal(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession, + SESSION *sess = NULL; + CK_BBOOL length_only = FALSE; + CK_RV rc = CKR_OK; ++ unsigned int mask; + + if (tokdata->initialized == FALSE) { + TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); +@@ -2670,10 +2693,18 @@ CK_RV SC_DecryptFinal(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession, + } + + rc = ep11tok_decrypt_final(tokdata, sess, pLastPart, pulLastPartLen); +- if (!is_rsa_mechanism(sess->decr_ctx.mech.mechanism) && rc != CKR_OK) ++ /* (!is_rsa_mechanism(sess->decr_ctx.mech.mechanism) && rc != CKR_OK) */ ++ mask = ~constant_time_is_zero( ++ is_rsa_mechanism(sess->decr_ctx.mech.mechanism)); ++ mask &= ~constant_time_eq(rc, CKR_OK); ++ if (mask) + TRACE_DEVEL("ep11tok_decrypt_final() failed.\n"); + done: +- if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) { ++ /* (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) */ ++ mask = ~constant_time_eq(rc, CKR_OK); ++ mask |= constant_time_is_zero(length_only); ++ mask &= ~constant_time_eq(rc, CKR_BUFFER_TOO_SMALL); ++ if (mask) { + if (sess) + decr_mgr_cleanup(tokdata, sess, &sess->decr_ctx); + } +diff --git a/usr/lib/icsf_stdll/new_host.c b/usr/lib/icsf_stdll/new_host.c +index 6c419750..d8064559 100644 +--- a/usr/lib/icsf_stdll/new_host.c ++++ b/usr/lib/icsf_stdll/new_host.c +@@ -35,6 +35,8 @@ + #include "slotmgr.h" + #include "attributes.h" + #include "icsf_specific.h" ++#include "constant_time.h" ++ + #include "../api/apiproto.h" + #include "../api/policy.h" + +@@ -1768,6 +1770,7 @@ CK_RV SC_Decrypt(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession, + SESSION *sess = NULL; + CK_BBOOL length_only = FALSE; + CK_RV rc = CKR_OK; ++ unsigned int mask; + + if (tokdata->initialized == FALSE) { + TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); +@@ -1801,11 +1804,19 @@ CK_RV SC_Decrypt(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession, + + rc = icsftok_decrypt(tokdata, sess, pEncryptedData, ulEncryptedDataLen, + pData, pulDataLen); +- if (!is_rsa_mechanism(sess->decr_ctx.mech.mechanism) && rc != CKR_OK) ++ /* (!is_rsa_mechanism(sess->decr_ctx.mech.mechanism) && rc != CKR_OK) */ ++ mask = ~constant_time_is_zero( ++ is_rsa_mechanism(sess->decr_ctx.mech.mechanism)); ++ mask &= ~constant_time_eq(rc, CKR_OK); ++ if (mask) + TRACE_DEVEL("icsftok_decrypt() failed.\n"); + + done: +- if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) { ++ /* (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) */ ++ mask = ~constant_time_eq(rc, CKR_OK); ++ mask |= constant_time_is_zero(length_only); ++ mask &= ~constant_time_eq(rc, CKR_BUFFER_TOO_SMALL); ++ if (mask) { + if (sess) + decr_mgr_cleanup(tokdata, sess, &sess->decr_ctx); + } +@@ -1827,6 +1838,7 @@ CK_RV SC_DecryptUpdate(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession, + { + SESSION *sess = NULL; + CK_RV rc = CKR_OK; ++ unsigned int mask; + + if (tokdata->initialized == FALSE) { + TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); +@@ -1857,11 +1869,18 @@ CK_RV SC_DecryptUpdate(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession, + + rc = icsftok_decrypt_update(tokdata, sess, pEncryptedPart, + ulEncryptedPartLen, pPart, pulPartLen); +- if (!is_rsa_mechanism(sess->decr_ctx.mech.mechanism) && rc != CKR_OK) ++ /* (!is_rsa_mechanism(sess->decr_ctx.mech.mechanism) && rc != CKR_OK) */ ++ mask = ~constant_time_is_zero( ++ is_rsa_mechanism(sess->decr_ctx.mech.mechanism)); ++ mask &= ~constant_time_eq(rc, CKR_OK); ++ if (mask) + TRACE_DEVEL("icsftok_decrypt_update() failed.\n"); + + done: +- if (rc != CKR_OK && rc != CKR_BUFFER_TOO_SMALL && sess != NULL) { ++ /* (rc != CKR_OK && rc != CKR_BUFFER_TOO_SMALL */ ++ mask = ~constant_time_eq(rc, CKR_OK); ++ mask &= ~constant_time_eq(rc, CKR_BUFFER_TOO_SMALL); ++ if (mask) { + if (sess) + decr_mgr_cleanup(tokdata, sess, &sess->decr_ctx); + } +@@ -1883,6 +1902,7 @@ CK_RV SC_DecryptFinal(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession, + SESSION *sess = NULL; + CK_BBOOL length_only = FALSE; + CK_RV rc = CKR_OK; ++ unsigned int mask; + + if (tokdata->initialized == FALSE) { + TRACE_ERROR("%s\n", ock_err(ERR_CRYPTOKI_NOT_INITIALIZED)); +@@ -1915,10 +1935,18 @@ CK_RV SC_DecryptFinal(STDLL_TokData_t *tokdata, ST_SESSION_HANDLE *sSession, + length_only = TRUE; + + rc = icsftok_decrypt_final(tokdata, sess, pLastPart, pulLastPartLen); +- if (!is_rsa_mechanism(sess->decr_ctx.mech.mechanism) && rc != CKR_OK) ++ /* (!is_rsa_mechanism(sess->decr_ctx.mech.mechanism) && rc != CKR_OK) */ ++ mask = ~constant_time_is_zero( ++ is_rsa_mechanism(sess->decr_ctx.mech.mechanism)); ++ mask &= ~constant_time_eq(rc, CKR_OK); ++ if (mask) + TRACE_DEVEL("icsftok_decrypt_final() failed.\n"); + done: +- if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) { ++ /* (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) */ ++ mask = ~constant_time_eq(rc, CKR_OK); ++ mask |= constant_time_is_zero(length_only); ++ mask &= ~constant_time_eq(rc, CKR_BUFFER_TOO_SMALL); ++ if (mask) { + if (sess) + decr_mgr_cleanup(tokdata, sess, &sess->decr_ctx); + } diff --git a/SOURCES/opencryptoki-CVE-2024-0914-part4.patch b/SOURCES/opencryptoki-CVE-2024-0914-part4.patch new file mode 100644 index 0000000..915b54f --- /dev/null +++ b/SOURCES/opencryptoki-CVE-2024-0914-part4.patch @@ -0,0 +1,1013 @@ +commit 7d064610937cdfb3cf8976adbb7eec6be3ea9d9f +Author: Ingo Franzki +Date: Tue Jan 16 10:01:20 2024 +0100 + + testcases: Add RSA implicit rejection test cases + + Signed-off-by: Ingo Franzki + +diff --git a/testcases/crypto/rsa.h b/testcases/crypto/rsa.h +index 7ed70262..6281d982 100644 +--- a/testcases/crypto/rsa.h ++++ b/testcases/crypto/rsa.h +@@ -8977,3 +8977,817 @@ struct PUBLISHED_TEST_SUITE_INFO rsa_encdec_import_test_suites[] = { + .mech = {CKM_RSA_X_509, 0, 0}, + }, + }; ++ ++struct RSA_PUBLISHED_TEST_VECTOR rsa_imp_rejection_tv[] = { ++ { // 0 - good case ++ .mod = {0xc8, 0xcc, 0x83, 0x97, 0x14, 0x09, 0x8d, 0xa5, ++ 0x6c, 0xaa, 0x23, 0x64, 0x0f, 0x93, 0xdc, 0x89, ++ 0x97, 0xc1, 0x63, 0x72, 0x96, 0x8f, 0xc1, 0xb0, ++ 0xc6, 0xdf, 0x51, 0x13, 0xc1, 0xc9, 0x4e, 0x8b, ++ 0x21, 0xe4, 0x8a, 0xd2, 0x29, 0x7e, 0x65, 0x41, ++ 0x90, 0x11, 0xb4, 0xe6, 0xd8, 0xf5, 0xe7, 0x3b, ++ 0x1b, 0x78, 0xb2, 0x57, 0x40, 0x03, 0x21, 0xd1, ++ 0xef, 0x6b, 0x60, 0x2d, 0x4e, 0xc8, 0xce, 0x8d, ++ 0x14, 0x1c, 0x94, 0x90, 0x5e, 0xb4, 0xad, 0x30, ++ 0x66, 0x39, 0xa4, 0x92, 0x06, 0x53, 0x4b, 0x6e, ++ 0x7f, 0x26, 0x07, 0x42, 0x3e, 0x97, 0xdf, 0xfd, ++ 0x13, 0x3c, 0x88, 0xd7, 0x21, 0x39, 0x9d, 0xef, ++ 0xbc, 0x7e, 0x96, 0xcc, 0xdc, 0xbd, 0x7f, 0x3a, ++ 0xae, 0x1f, 0xe8, 0x92, 0x71, 0x2b, 0xfb, 0x49, ++ 0x29, 0x81, 0x7d, 0x51, 0x16, 0x66, 0x44, 0x0a, ++ 0x1f, 0xac, 0xb7, 0xa2, 0x08, 0xf5, 0xea, 0x16, ++ 0x59, 0x10, 0xad, 0xd8, 0xa3, 0xf2, 0xd4, 0x97, ++ 0x20, 0x23, 0x60, 0xcc, 0xb6, 0x32, 0x02, 0x4f, ++ 0x0d, 0x07, 0x16, 0x9c, 0x19, 0x18, 0xf3, 0x16, ++ 0xf7, 0x94, 0xb1, 0x43, 0xae, 0xf5, 0x4e, 0xc8, ++ 0x75, 0x22, 0xa4, 0xc0, 0x29, 0x78, 0xf9, 0x68, ++ 0x99, 0x80, 0xbf, 0xfb, 0xf6, 0x49, 0xc3, 0x07, ++ 0xe8, 0x18, 0x19, 0xbf, 0xf8, 0x84, 0x09, 0x63, ++ 0x8d, 0x48, 0xbd, 0x94, 0xbe, 0x15, 0x2b, 0x59, ++ 0xff, 0x64, 0x9f, 0xa0, 0xbd, 0x62, 0x9d, 0x0f, ++ 0xfa, 0x18, 0x13, 0xc3, 0xab, 0xf4, 0xb5, 0x6b, ++ 0xd3, 0xc2, 0xea, 0x54, 0x65, 0xdf, 0xfa, 0x14, ++ 0x58, 0x92, 0x92, 0xa9, 0xd8, 0xa2, 0x4a, 0xd2, ++ 0x6b, 0xe7, 0xee, 0x05, 0x10, 0x74, 0x1b, 0x63, ++ 0x82, 0xd4, 0x3c, 0x83, 0xd5, 0xbf, 0xa4, 0x0a, ++ 0x46, 0x61, 0x3d, 0x06, 0x2b, 0xe4, 0x45, 0x51, ++ 0x7d, 0xbc, 0xaf, 0x0c, 0xb4, 0xe1, 0xa7, 0x69}, ++ .mod_len = 256, ++ .pub_exp = {0x01, 0x00, 0x01}, ++ .pubexp_len = 3, ++ .priv_exp = {0x14, 0x55, 0x01, 0x0e, 0x0f, 0x2d, 0x58, 0x76, ++ 0x63, 0xa6, 0x66, 0xa6, 0xff, 0x1c, 0xcd, 0xbb, ++ 0xf0, 0xed, 0xd8, 0x10, 0x06, 0x46, 0xd0, 0x2a, ++ 0x02, 0x39, 0x22, 0x90, 0x89, 0x92, 0xc4, 0xad, ++ 0x39, 0xe5, 0x56, 0x59, 0x29, 0x72, 0x6e, 0xf6, ++ 0x50, 0x8c, 0x3a, 0x71, 0x15, 0x8e, 0xf0, 0xb6, ++ 0xff, 0x75, 0x1d, 0x39, 0xd0, 0x75, 0x80, 0xbb, ++ 0x2d, 0x2f, 0x06, 0x32, 0x10, 0x44, 0x2d, 0x06, ++ 0x03, 0xff, 0x50, 0xdb, 0xbd, 0x7b, 0x35, 0xfe, ++ 0x2c, 0x9b, 0xb1, 0x9a, 0x47, 0xa1, 0xaf, 0x85, ++ 0xa4, 0xc2, 0x49, 0x01, 0xe0, 0x2c, 0xa8, 0xb5, ++ 0x8b, 0x79, 0x19, 0xb2, 0x0e, 0xdf, 0x32, 0xaa, ++ 0xcf, 0xbf, 0x51, 0xad, 0xb4, 0xbc, 0x4b, 0x61, ++ 0xb9, 0xb7, 0xe9, 0x68, 0xca, 0xa4, 0xd5, 0x70, ++ 0xf7, 0x0e, 0xf1, 0x8d, 0x80, 0x63, 0x22, 0x88, ++ 0x93, 0xe4, 0x7d, 0x43, 0x9e, 0xfc, 0xa7, 0x93, ++ 0x25, 0x9b, 0xcf, 0x2c, 0xd1, 0x08, 0xa3, 0xd8, ++ 0x68, 0x8c, 0xdf, 0x07, 0x8e, 0x7a, 0xc7, 0x99, ++ 0x96, 0x9f, 0x23, 0x39, 0xd2, 0xc1, 0xf5, 0x22, ++ 0xb9, 0x69, 0x68, 0x46, 0x29, 0xa9, 0x33, 0xba, ++ 0xae, 0xc2, 0x68, 0x16, 0x25, 0xea, 0xb8, 0x4f, ++ 0x4e, 0x56, 0xf4, 0x44, 0x7e, 0x9d, 0x88, 0xfb, ++ 0x9a, 0x19, 0x9c, 0xf7, 0x10, 0x23, 0xe0, 0xe2, ++ 0x57, 0xb1, 0x44, 0x41, 0xb3, 0x3c, 0x84, 0xd3, ++ 0xbc, 0x67, 0xca, 0x80, 0x31, 0xd2, 0x61, 0x26, ++ 0x18, 0x10, 0x3a, 0x7a, 0x0a, 0x40, 0x84, 0x42, ++ 0x62, 0xf7, 0x5d, 0x88, 0x90, 0xcd, 0x61, 0x6e, ++ 0x51, 0xf9, 0x03, 0x54, 0x88, 0xfd, 0x6e, 0x09, ++ 0x9d, 0xe8, 0xff, 0x6d, 0x65, 0xa4, 0xff, 0x11, ++ 0x82, 0x54, 0x80, 0x7c, 0x9f, 0x58, 0xd2, 0xfb, ++ 0xba, 0x8b, 0xa1, 0x51, 0xdc, 0x8c, 0x68, 0xbe, ++ 0x34, 0x9c, 0x97, 0x7a, 0x20, 0x4e, 0x04, 0xc1}, ++ .privexp_len = 256, ++ .prime1 = {0xf8, 0xf5, 0xad, 0x6b, 0xa8, 0x28, 0x93, 0x1b, ++ 0xea, 0x45, 0x9b, 0x8a, 0x3f, 0x6d, 0xc0, 0x41, ++ 0xd2, 0x34, 0x82, 0x40, 0x9c, 0x25, 0x71, 0xe9, ++ 0x63, 0xf3, 0x1f, 0x74, 0x86, 0x02, 0xa2, 0x56, ++ 0x37, 0x1b, 0x38, 0x83, 0xed, 0x45, 0x9e, 0xcf, ++ 0x97, 0x05, 0x26, 0x45, 0x9e, 0xdd, 0x16, 0xe0, ++ 0x55, 0x22, 0xf5, 0xa4, 0x5d, 0x94, 0x75, 0x1b, ++ 0x2e, 0xc2, 0xda, 0xf2, 0x72, 0xc7, 0xf8, 0x81, ++ 0x6a, 0x52, 0xc0, 0x0d, 0x18, 0x08, 0x01, 0x71, ++ 0x63, 0x4d, 0xa8, 0x99, 0xd7, 0x97, 0x32, 0x22, ++ 0xf5, 0x1b, 0x93, 0x76, 0x30, 0x54, 0x86, 0x96, ++ 0xa9, 0xf7, 0xd8, 0xc2, 0x4a, 0x59, 0x49, 0x7c, ++ 0x1e, 0xfc, 0xd4, 0x55, 0xcf, 0xb9, 0x7e, 0xe8, ++ 0x6d, 0x2b, 0x6d, 0x34, 0x97, 0x2b, 0x33, 0x2f, ++ 0xda, 0x30, 0x3f, 0x04, 0x99, 0x9b, 0x4e, 0xb6, ++ 0xb5, 0xcc, 0x0b, 0xb3, 0x3e, 0x77, 0x61, 0xdd}, ++ .prime1_len = 128, ++ .prime2 = {0xce, 0x7a, 0x2e, 0x3b, 0x49, 0xa9, 0x0b, 0x96, ++ 0x33, 0x0a, 0x12, 0xdc, 0x68, 0x2b, 0xdf, 0xbd, ++ 0xfb, 0xae, 0x8d, 0xd6, 0xdc, 0x03, 0xb6, 0x14, ++ 0x7a, 0xef, 0xbd, 0x57, 0x57, 0x43, 0xf0, 0xf6, ++ 0xda, 0x4d, 0x86, 0x23, 0x50, 0x61, 0xb7, 0x1a, ++ 0xfd, 0x9c, 0xad, 0x2d, 0x34, 0x02, 0x5e, 0x56, ++ 0xac, 0x86, 0xb0, 0xf7, 0x74, 0x3e, 0xb3, 0x5e, ++ 0x1a, 0xcb, 0xca, 0x23, 0x78, 0x95, 0x42, 0x44, ++ 0x65, 0xb7, 0x06, 0xed, 0x22, 0x17, 0x5e, 0x57, ++ 0x18, 0xc8, 0xc7, 0x0b, 0x67, 0x03, 0xea, 0x8f, ++ 0x6b, 0x51, 0x0f, 0x94, 0x5b, 0xe4, 0x8e, 0x5a, ++ 0x36, 0xbb, 0x3c, 0x3c, 0x91, 0x73, 0x2b, 0x58, ++ 0x9d, 0xfc, 0x05, 0xd7, 0x2d, 0x80, 0x90, 0x31, ++ 0x94, 0x45, 0x2b, 0xda, 0x21, 0x34, 0x86, 0x47, ++ 0xec, 0x72, 0x94, 0x3f, 0x11, 0xa8, 0x46, 0xe6, ++ 0x2f, 0xae, 0xbe, 0x8e, 0xb5, 0x36, 0xb0, 0xfd}, ++ .prime2_len = 128, ++ .exp1 = {0x76, 0xfe, 0x15, 0xf1, 0x8a, 0xe2, 0x39, 0xcd, ++ 0xf1, 0xdf, 0x6b, 0x44, 0x5c, 0xa4, 0xbc, 0x6b, ++ 0xb9, 0x68, 0xd7, 0x88, 0xc2, 0x19, 0x33, 0xa4, ++ 0xf5, 0xdc, 0xd2, 0x80, 0x03, 0x3d, 0x67, 0x12, ++ 0x06, 0x2c, 0xc0, 0x8a, 0x6d, 0xf2, 0x04, 0xc1, ++ 0xfb, 0xd0, 0xbe, 0x46, 0x30, 0x74, 0x43, 0xe6, ++ 0xdd, 0x4a, 0x64, 0x56, 0x37, 0x54, 0x29, 0xd4, ++ 0xe0, 0x38, 0xca, 0x25, 0x6f, 0xaf, 0x1c, 0x9b, ++ 0xde, 0x91, 0xc6, 0xb1, 0x7b, 0x76, 0xf8, 0x19, ++ 0x95, 0xf9, 0x1c, 0x48, 0xcb, 0xbe, 0xbc, 0x7b, ++ 0xf0, 0xe3, 0x49, 0x4c, 0x08, 0x35, 0x9e, 0x4e, ++ 0x8c, 0xd6, 0xa5, 0x87, 0xd7, 0xb9, 0x6d, 0x62, ++ 0x21, 0xfd, 0x7e, 0x0f, 0xb5, 0xc5, 0x57, 0x5f, ++ 0x08, 0x2e, 0xe5, 0x77, 0x69, 0x79, 0x80, 0x71, ++ 0xb2, 0xbb, 0xb4, 0xa3, 0x22, 0x38, 0x15, 0x1b, ++ 0x47, 0x31, 0x4b, 0xb6, 0x54, 0x79, 0x03, 0x11}, ++ .exp1_len = 128, ++ .exp2 = {0x99, 0x88, 0x48, 0xb0, 0x55, 0x49, 0x9a, 0x10, ++ 0x09, 0xcb, 0xc7, 0xd2, 0x94, 0xb3, 0x6b, 0x1f, ++ 0xfd, 0xf2, 0x02, 0x0e, 0x6e, 0x73, 0x64, 0x05, ++ 0x3e, 0x94, 0xde, 0x1a, 0x00, 0x0d, 0xc9, 0x34, ++ 0x05, 0x87, 0xf7, 0xe2, 0x72, 0x76, 0xf6, 0x8c, ++ 0xdf, 0x60, 0x8d, 0x75, 0x3b, 0x63, 0x37, 0x7b, ++ 0x03, 0xb6, 0xf4, 0x08, 0x4d, 0x2c, 0x02, 0x7c, ++ 0x4b, 0x38, 0x96, 0x0a, 0x62, 0x33, 0xba, 0x9e, ++ 0xd9, 0x73, 0x8b, 0x76, 0xf1, 0x0e, 0xa7, 0x5b, ++ 0xe4, 0x56, 0x07, 0x8b, 0xf7, 0x01, 0xf6, 0x7c, ++ 0xc6, 0xb3, 0xf3, 0xfd, 0xc1, 0x86, 0xe6, 0x43, ++ 0x36, 0xc7, 0x6b, 0x37, 0x2e, 0x80, 0x91, 0x0e, ++ 0xc8, 0x0b, 0x0a, 0xdc, 0xc2, 0x3d, 0x02, 0xfb, ++ 0x9a, 0xe1, 0x04, 0x86, 0xa2, 0x82, 0x48, 0x07, ++ 0x5b, 0x4e, 0xa7, 0xe5, 0x6d, 0xdf, 0xcf, 0x38, ++ 0x82, 0xe4, 0x51, 0x56, 0x14, 0x71, 0xa2, 0x91}, ++ .exp2_len = 128, ++ .coef = {0x64, 0x3b, 0xf7, 0x46, 0x42, 0x9f, 0x7d, 0x83, ++ 0x66, 0x7a, 0x06, 0x53, 0x02, 0x13, 0x47, 0xef, ++ 0xbf, 0xc0, 0x5e, 0x63, 0x51, 0xf8, 0x21, 0xa9, ++ 0xde, 0xbb, 0x60, 0xe0, 0xec, 0xcd, 0xe5, 0x00, ++ 0x5a, 0xd9, 0xe9, 0xec, 0x31, 0xe5, 0x58, 0xf7, ++ 0xe9, 0x2c, 0x29, 0x32, 0x8e, 0x74, 0x56, 0x9d, ++ 0x7c, 0xef, 0x7c, 0x74, 0xca, 0xbc, 0x2b, 0x35, ++ 0x5e, 0xd4, 0x01, 0xa1, 0xa0, 0x91, 0x4b, 0x4e, ++ 0x3c, 0xbb, 0x06, 0x48, 0x4e, 0x58, 0x19, 0x60, ++ 0x51, 0x16, 0x9e, 0xd1, 0x4c, 0xaa, 0x2e, 0xfa, ++ 0x6e, 0xa0, 0x44, 0xe0, 0x54, 0xd2, 0x61, 0x44, ++ 0xcc, 0x16, 0x29, 0xc5, 0x50, 0x10, 0x55, 0x8a, ++ 0x04, 0xe1, 0x33, 0xf4, 0x4b, 0x7c, 0x24, 0x4d, ++ 0xac, 0x25, 0xbf, 0x91, 0x3c, 0x57, 0xb8, 0x90, ++ 0xee, 0x49, 0xf5, 0x48, 0x25, 0x9c, 0xd6, 0x34, ++ 0x04, 0xfe, 0xf6, 0x85, 0x9d, 0xcf, 0x97, 0x5a}, ++ .coef_len = 128, ++ // msg is encrypted message ++ .msg = {0x8b, 0xfe, 0x26, 0x4e, 0x85, 0xd3, 0xbd, 0xea, ++ 0xa6, 0xb8, 0x85, 0x1b, 0x8e, 0x3b, 0x95, 0x6e, ++ 0xe3, 0xd2, 0x26, 0xfd, 0x3f, 0x69, 0x06, 0x3a, ++ 0x86, 0x88, 0x01, 0x73, 0xa2, 0x73, 0xd9, 0xf2, ++ 0x83, 0xb2, 0xee, 0xbd, 0xd1, 0xed, 0x35, 0xf7, ++ 0xe0, 0x2d, 0x91, 0xc5, 0x71, 0x98, 0x1b, 0x67, ++ 0x37, 0xd5, 0x32, 0x0b, 0xd8, 0x39, 0x6b, 0x0f, ++ 0x3a, 0xd5, 0xb0, 0x19, 0xda, 0xec, 0x1b, 0x0a, ++ 0xab, 0x3c, 0xbb, 0xc0, 0x26, 0x39, 0x5f, 0x4f, ++ 0xd1, 0x4f, 0x13, 0x67, 0x3f, 0x2d, 0xfc, 0x81, ++ 0xf9, 0xb6, 0x60, 0xec, 0x26, 0xac, 0x38, 0x1e, ++ 0x6d, 0xb3, 0x29, 0x9b, 0x4e, 0x46, 0x0b, 0x43, ++ 0xfa, 0xb9, 0x95, 0x5d, 0xf2, 0xb3, 0xcf, 0xaa, ++ 0x20, 0xe9, 0x00, 0xe1, 0x9c, 0x85, 0x62, 0x38, ++ 0xfd, 0x37, 0x18, 0x99, 0xc2, 0xbf, 0x2c, 0xe8, ++ 0xc8, 0x68, 0xb7, 0x67, 0x54, 0xe5, 0xdb, 0x3b, ++ 0x03, 0x65, 0x33, 0xfd, 0x60, 0x37, 0x46, 0xbe, ++ 0x13, 0xc1, 0x0d, 0x4e, 0x3e, 0x60, 0x22, 0xeb, ++ 0xc9, 0x05, 0xd2, 0x0c, 0x2a, 0x7f, 0x32, 0xb2, ++ 0x15, 0xa4, 0xcd, 0x53, 0xb3, 0xf4, 0x4c, 0xa1, ++ 0xc3, 0x27, 0xd2, 0xc2, 0xb6, 0x51, 0x14, 0x58, ++ 0x21, 0xc0, 0x83, 0x96, 0xc8, 0x90, 0x71, 0xf6, ++ 0x65, 0x34, 0x9c, 0x25, 0xe4, 0x4d, 0x27, 0x33, ++ 0xcd, 0x93, 0x05, 0x98, 0x5c, 0xee, 0xf6, 0x43, ++ 0x0c, 0x3c, 0xf5, 0x7a, 0xf5, 0xfa, 0x22, 0x40, ++ 0x89, 0x22, 0x12, 0x18, 0xfa, 0x34, 0x73, 0x7c, ++ 0x79, 0xc4, 0x46, 0xd2, 0x8a, 0x94, 0xc4, 0x1c, ++ 0x96, 0xe4, 0xe9, 0x2a, 0xc5, 0x3f, 0xbc, 0xf3, ++ 0x84, 0xde, 0xa8, 0x41, 0x9e, 0xa0, 0x89, 0xf8, ++ 0x78, 0x44, 0x45, 0xa4, 0x92, 0xc8, 0x12, 0xeb, ++ 0x0d, 0x40, 0x94, 0x67, 0xf7, 0x5a, 0xfd, 0x7d, ++ 0x4d, 0x10, 0x78, 0x88, 0x62, 0x05, 0xa0, 0x66}, ++ .msg_len = 256, ++ // sig is decrypted message ++ .sig = { 0x6c, 0x6f, 0x72, 0x65, 0x6d, 0x20, 0x69, 0x70, ++ 0x73, 0x75, 0x6d, 0x20, 0x64, 0x6f, 0x6c, 0x6f, ++ 0x72, 0x20, 0x73, 0x69, 0x74, 0x20, 0x61, 0x6d, ++ 0x65, 0x74}, ++ .sig_len = 26, ++ }, ++ { // 1 - bad, empty input ++ .mod = {0xc8, 0xcc, 0x83, 0x97, 0x14, 0x09, 0x8d, 0xa5, ++ 0x6c, 0xaa, 0x23, 0x64, 0x0f, 0x93, 0xdc, 0x89, ++ 0x97, 0xc1, 0x63, 0x72, 0x96, 0x8f, 0xc1, 0xb0, ++ 0xc6, 0xdf, 0x51, 0x13, 0xc1, 0xc9, 0x4e, 0x8b, ++ 0x21, 0xe4, 0x8a, 0xd2, 0x29, 0x7e, 0x65, 0x41, ++ 0x90, 0x11, 0xb4, 0xe6, 0xd8, 0xf5, 0xe7, 0x3b, ++ 0x1b, 0x78, 0xb2, 0x57, 0x40, 0x03, 0x21, 0xd1, ++ 0xef, 0x6b, 0x60, 0x2d, 0x4e, 0xc8, 0xce, 0x8d, ++ 0x14, 0x1c, 0x94, 0x90, 0x5e, 0xb4, 0xad, 0x30, ++ 0x66, 0x39, 0xa4, 0x92, 0x06, 0x53, 0x4b, 0x6e, ++ 0x7f, 0x26, 0x07, 0x42, 0x3e, 0x97, 0xdf, 0xfd, ++ 0x13, 0x3c, 0x88, 0xd7, 0x21, 0x39, 0x9d, 0xef, ++ 0xbc, 0x7e, 0x96, 0xcc, 0xdc, 0xbd, 0x7f, 0x3a, ++ 0xae, 0x1f, 0xe8, 0x92, 0x71, 0x2b, 0xfb, 0x49, ++ 0x29, 0x81, 0x7d, 0x51, 0x16, 0x66, 0x44, 0x0a, ++ 0x1f, 0xac, 0xb7, 0xa2, 0x08, 0xf5, 0xea, 0x16, ++ 0x59, 0x10, 0xad, 0xd8, 0xa3, 0xf2, 0xd4, 0x97, ++ 0x20, 0x23, 0x60, 0xcc, 0xb6, 0x32, 0x02, 0x4f, ++ 0x0d, 0x07, 0x16, 0x9c, 0x19, 0x18, 0xf3, 0x16, ++ 0xf7, 0x94, 0xb1, 0x43, 0xae, 0xf5, 0x4e, 0xc8, ++ 0x75, 0x22, 0xa4, 0xc0, 0x29, 0x78, 0xf9, 0x68, ++ 0x99, 0x80, 0xbf, 0xfb, 0xf6, 0x49, 0xc3, 0x07, ++ 0xe8, 0x18, 0x19, 0xbf, 0xf8, 0x84, 0x09, 0x63, ++ 0x8d, 0x48, 0xbd, 0x94, 0xbe, 0x15, 0x2b, 0x59, ++ 0xff, 0x64, 0x9f, 0xa0, 0xbd, 0x62, 0x9d, 0x0f, ++ 0xfa, 0x18, 0x13, 0xc3, 0xab, 0xf4, 0xb5, 0x6b, ++ 0xd3, 0xc2, 0xea, 0x54, 0x65, 0xdf, 0xfa, 0x14, ++ 0x58, 0x92, 0x92, 0xa9, 0xd8, 0xa2, 0x4a, 0xd2, ++ 0x6b, 0xe7, 0xee, 0x05, 0x10, 0x74, 0x1b, 0x63, ++ 0x82, 0xd4, 0x3c, 0x83, 0xd5, 0xbf, 0xa4, 0x0a, ++ 0x46, 0x61, 0x3d, 0x06, 0x2b, 0xe4, 0x45, 0x51, ++ 0x7d, 0xbc, 0xaf, 0x0c, 0xb4, 0xe1, 0xa7, 0x69}, ++ .mod_len = 256, ++ .pub_exp = {0x01, 0x00, 0x01}, ++ .pubexp_len = 3, ++ .priv_exp = {0x14, 0x55, 0x01, 0x0e, 0x0f, 0x2d, 0x58, 0x76, ++ 0x63, 0xa6, 0x66, 0xa6, 0xff, 0x1c, 0xcd, 0xbb, ++ 0xf0, 0xed, 0xd8, 0x10, 0x06, 0x46, 0xd0, 0x2a, ++ 0x02, 0x39, 0x22, 0x90, 0x89, 0x92, 0xc4, 0xad, ++ 0x39, 0xe5, 0x56, 0x59, 0x29, 0x72, 0x6e, 0xf6, ++ 0x50, 0x8c, 0x3a, 0x71, 0x15, 0x8e, 0xf0, 0xb6, ++ 0xff, 0x75, 0x1d, 0x39, 0xd0, 0x75, 0x80, 0xbb, ++ 0x2d, 0x2f, 0x06, 0x32, 0x10, 0x44, 0x2d, 0x06, ++ 0x03, 0xff, 0x50, 0xdb, 0xbd, 0x7b, 0x35, 0xfe, ++ 0x2c, 0x9b, 0xb1, 0x9a, 0x47, 0xa1, 0xaf, 0x85, ++ 0xa4, 0xc2, 0x49, 0x01, 0xe0, 0x2c, 0xa8, 0xb5, ++ 0x8b, 0x79, 0x19, 0xb2, 0x0e, 0xdf, 0x32, 0xaa, ++ 0xcf, 0xbf, 0x51, 0xad, 0xb4, 0xbc, 0x4b, 0x61, ++ 0xb9, 0xb7, 0xe9, 0x68, 0xca, 0xa4, 0xd5, 0x70, ++ 0xf7, 0x0e, 0xf1, 0x8d, 0x80, 0x63, 0x22, 0x88, ++ 0x93, 0xe4, 0x7d, 0x43, 0x9e, 0xfc, 0xa7, 0x93, ++ 0x25, 0x9b, 0xcf, 0x2c, 0xd1, 0x08, 0xa3, 0xd8, ++ 0x68, 0x8c, 0xdf, 0x07, 0x8e, 0x7a, 0xc7, 0x99, ++ 0x96, 0x9f, 0x23, 0x39, 0xd2, 0xc1, 0xf5, 0x22, ++ 0xb9, 0x69, 0x68, 0x46, 0x29, 0xa9, 0x33, 0xba, ++ 0xae, 0xc2, 0x68, 0x16, 0x25, 0xea, 0xb8, 0x4f, ++ 0x4e, 0x56, 0xf4, 0x44, 0x7e, 0x9d, 0x88, 0xfb, ++ 0x9a, 0x19, 0x9c, 0xf7, 0x10, 0x23, 0xe0, 0xe2, ++ 0x57, 0xb1, 0x44, 0x41, 0xb3, 0x3c, 0x84, 0xd3, ++ 0xbc, 0x67, 0xca, 0x80, 0x31, 0xd2, 0x61, 0x26, ++ 0x18, 0x10, 0x3a, 0x7a, 0x0a, 0x40, 0x84, 0x42, ++ 0x62, 0xf7, 0x5d, 0x88, 0x90, 0xcd, 0x61, 0x6e, ++ 0x51, 0xf9, 0x03, 0x54, 0x88, 0xfd, 0x6e, 0x09, ++ 0x9d, 0xe8, 0xff, 0x6d, 0x65, 0xa4, 0xff, 0x11, ++ 0x82, 0x54, 0x80, 0x7c, 0x9f, 0x58, 0xd2, 0xfb, ++ 0xba, 0x8b, 0xa1, 0x51, 0xdc, 0x8c, 0x68, 0xbe, ++ 0x34, 0x9c, 0x97, 0x7a, 0x20, 0x4e, 0x04, 0xc1}, ++ .privexp_len = 256, ++ .prime1 = {0xf8, 0xf5, 0xad, 0x6b, 0xa8, 0x28, 0x93, 0x1b, ++ 0xea, 0x45, 0x9b, 0x8a, 0x3f, 0x6d, 0xc0, 0x41, ++ 0xd2, 0x34, 0x82, 0x40, 0x9c, 0x25, 0x71, 0xe9, ++ 0x63, 0xf3, 0x1f, 0x74, 0x86, 0x02, 0xa2, 0x56, ++ 0x37, 0x1b, 0x38, 0x83, 0xed, 0x45, 0x9e, 0xcf, ++ 0x97, 0x05, 0x26, 0x45, 0x9e, 0xdd, 0x16, 0xe0, ++ 0x55, 0x22, 0xf5, 0xa4, 0x5d, 0x94, 0x75, 0x1b, ++ 0x2e, 0xc2, 0xda, 0xf2, 0x72, 0xc7, 0xf8, 0x81, ++ 0x6a, 0x52, 0xc0, 0x0d, 0x18, 0x08, 0x01, 0x71, ++ 0x63, 0x4d, 0xa8, 0x99, 0xd7, 0x97, 0x32, 0x22, ++ 0xf5, 0x1b, 0x93, 0x76, 0x30, 0x54, 0x86, 0x96, ++ 0xa9, 0xf7, 0xd8, 0xc2, 0x4a, 0x59, 0x49, 0x7c, ++ 0x1e, 0xfc, 0xd4, 0x55, 0xcf, 0xb9, 0x7e, 0xe8, ++ 0x6d, 0x2b, 0x6d, 0x34, 0x97, 0x2b, 0x33, 0x2f, ++ 0xda, 0x30, 0x3f, 0x04, 0x99, 0x9b, 0x4e, 0xb6, ++ 0xb5, 0xcc, 0x0b, 0xb3, 0x3e, 0x77, 0x61, 0xdd}, ++ .prime1_len = 128, ++ .prime2 = {0xce, 0x7a, 0x2e, 0x3b, 0x49, 0xa9, 0x0b, 0x96, ++ 0x33, 0x0a, 0x12, 0xdc, 0x68, 0x2b, 0xdf, 0xbd, ++ 0xfb, 0xae, 0x8d, 0xd6, 0xdc, 0x03, 0xb6, 0x14, ++ 0x7a, 0xef, 0xbd, 0x57, 0x57, 0x43, 0xf0, 0xf6, ++ 0xda, 0x4d, 0x86, 0x23, 0x50, 0x61, 0xb7, 0x1a, ++ 0xfd, 0x9c, 0xad, 0x2d, 0x34, 0x02, 0x5e, 0x56, ++ 0xac, 0x86, 0xb0, 0xf7, 0x74, 0x3e, 0xb3, 0x5e, ++ 0x1a, 0xcb, 0xca, 0x23, 0x78, 0x95, 0x42, 0x44, ++ 0x65, 0xb7, 0x06, 0xed, 0x22, 0x17, 0x5e, 0x57, ++ 0x18, 0xc8, 0xc7, 0x0b, 0x67, 0x03, 0xea, 0x8f, ++ 0x6b, 0x51, 0x0f, 0x94, 0x5b, 0xe4, 0x8e, 0x5a, ++ 0x36, 0xbb, 0x3c, 0x3c, 0x91, 0x73, 0x2b, 0x58, ++ 0x9d, 0xfc, 0x05, 0xd7, 0x2d, 0x80, 0x90, 0x31, ++ 0x94, 0x45, 0x2b, 0xda, 0x21, 0x34, 0x86, 0x47, ++ 0xec, 0x72, 0x94, 0x3f, 0x11, 0xa8, 0x46, 0xe6, ++ 0x2f, 0xae, 0xbe, 0x8e, 0xb5, 0x36, 0xb0, 0xfd}, ++ .prime2_len = 128, ++ .exp1 = {0x76, 0xfe, 0x15, 0xf1, 0x8a, 0xe2, 0x39, 0xcd, ++ 0xf1, 0xdf, 0x6b, 0x44, 0x5c, 0xa4, 0xbc, 0x6b, ++ 0xb9, 0x68, 0xd7, 0x88, 0xc2, 0x19, 0x33, 0xa4, ++ 0xf5, 0xdc, 0xd2, 0x80, 0x03, 0x3d, 0x67, 0x12, ++ 0x06, 0x2c, 0xc0, 0x8a, 0x6d, 0xf2, 0x04, 0xc1, ++ 0xfb, 0xd0, 0xbe, 0x46, 0x30, 0x74, 0x43, 0xe6, ++ 0xdd, 0x4a, 0x64, 0x56, 0x37, 0x54, 0x29, 0xd4, ++ 0xe0, 0x38, 0xca, 0x25, 0x6f, 0xaf, 0x1c, 0x9b, ++ 0xde, 0x91, 0xc6, 0xb1, 0x7b, 0x76, 0xf8, 0x19, ++ 0x95, 0xf9, 0x1c, 0x48, 0xcb, 0xbe, 0xbc, 0x7b, ++ 0xf0, 0xe3, 0x49, 0x4c, 0x08, 0x35, 0x9e, 0x4e, ++ 0x8c, 0xd6, 0xa5, 0x87, 0xd7, 0xb9, 0x6d, 0x62, ++ 0x21, 0xfd, 0x7e, 0x0f, 0xb5, 0xc5, 0x57, 0x5f, ++ 0x08, 0x2e, 0xe5, 0x77, 0x69, 0x79, 0x80, 0x71, ++ 0xb2, 0xbb, 0xb4, 0xa3, 0x22, 0x38, 0x15, 0x1b, ++ 0x47, 0x31, 0x4b, 0xb6, 0x54, 0x79, 0x03, 0x11}, ++ .exp1_len = 128, ++ .exp2 = {0x99, 0x88, 0x48, 0xb0, 0x55, 0x49, 0x9a, 0x10, ++ 0x09, 0xcb, 0xc7, 0xd2, 0x94, 0xb3, 0x6b, 0x1f, ++ 0xfd, 0xf2, 0x02, 0x0e, 0x6e, 0x73, 0x64, 0x05, ++ 0x3e, 0x94, 0xde, 0x1a, 0x00, 0x0d, 0xc9, 0x34, ++ 0x05, 0x87, 0xf7, 0xe2, 0x72, 0x76, 0xf6, 0x8c, ++ 0xdf, 0x60, 0x8d, 0x75, 0x3b, 0x63, 0x37, 0x7b, ++ 0x03, 0xb6, 0xf4, 0x08, 0x4d, 0x2c, 0x02, 0x7c, ++ 0x4b, 0x38, 0x96, 0x0a, 0x62, 0x33, 0xba, 0x9e, ++ 0xd9, 0x73, 0x8b, 0x76, 0xf1, 0x0e, 0xa7, 0x5b, ++ 0xe4, 0x56, 0x07, 0x8b, 0xf7, 0x01, 0xf6, 0x7c, ++ 0xc6, 0xb3, 0xf3, 0xfd, 0xc1, 0x86, 0xe6, 0x43, ++ 0x36, 0xc7, 0x6b, 0x37, 0x2e, 0x80, 0x91, 0x0e, ++ 0xc8, 0x0b, 0x0a, 0xdc, 0xc2, 0x3d, 0x02, 0xfb, ++ 0x9a, 0xe1, 0x04, 0x86, 0xa2, 0x82, 0x48, 0x07, ++ 0x5b, 0x4e, 0xa7, 0xe5, 0x6d, 0xdf, 0xcf, 0x38, ++ 0x82, 0xe4, 0x51, 0x56, 0x14, 0x71, 0xa2, 0x91}, ++ .exp2_len = 128, ++ .coef = {0x64, 0x3b, 0xf7, 0x46, 0x42, 0x9f, 0x7d, 0x83, ++ 0x66, 0x7a, 0x06, 0x53, 0x02, 0x13, 0x47, 0xef, ++ 0xbf, 0xc0, 0x5e, 0x63, 0x51, 0xf8, 0x21, 0xa9, ++ 0xde, 0xbb, 0x60, 0xe0, 0xec, 0xcd, 0xe5, 0x00, ++ 0x5a, 0xd9, 0xe9, 0xec, 0x31, 0xe5, 0x58, 0xf7, ++ 0xe9, 0x2c, 0x29, 0x32, 0x8e, 0x74, 0x56, 0x9d, ++ 0x7c, 0xef, 0x7c, 0x74, 0xca, 0xbc, 0x2b, 0x35, ++ 0x5e, 0xd4, 0x01, 0xa1, 0xa0, 0x91, 0x4b, 0x4e, ++ 0x3c, 0xbb, 0x06, 0x48, 0x4e, 0x58, 0x19, 0x60, ++ 0x51, 0x16, 0x9e, 0xd1, 0x4c, 0xaa, 0x2e, 0xfa, ++ 0x6e, 0xa0, 0x44, 0xe0, 0x54, 0xd2, 0x61, 0x44, ++ 0xcc, 0x16, 0x29, 0xc5, 0x50, 0x10, 0x55, 0x8a, ++ 0x04, 0xe1, 0x33, 0xf4, 0x4b, 0x7c, 0x24, 0x4d, ++ 0xac, 0x25, 0xbf, 0x91, 0x3c, 0x57, 0xb8, 0x90, ++ 0xee, 0x49, 0xf5, 0x48, 0x25, 0x9c, 0xd6, 0x34, ++ 0x04, 0xfe, 0xf6, 0x85, 0x9d, 0xcf, 0x97, 0x5a}, ++ .coef_len = 128, ++ // msg is encrypted message ++ .msg = {0x20, 0xaa, 0xa8, 0xad, 0xbb, 0xc5, 0x93, 0xa9, ++ 0x24, 0xba, 0x1c, 0x5c, 0x79, 0x90, 0xb5, 0xc2, ++ 0x24, 0x2a, 0xe4, 0xb9, 0x9d, 0x0f, 0xe6, 0x36, ++ 0xa1, 0x9a, 0x4c, 0xf7, 0x54, 0xed, 0xbc, 0xee, ++ 0x77, 0x4e, 0x47, 0x2f, 0xe0, 0x28, 0x16, 0x0e, ++ 0xd4, 0x26, 0x34, 0xf8, 0x86, 0x49, 0x00, 0xcb, ++ 0x51, 0x40, 0x06, 0xda, 0x64, 0x2c, 0xae, 0x6a, ++ 0xe8, 0xc7, 0xd0, 0x87, 0xca, 0xeb, 0xcf, 0xa6, ++ 0xda, 0xd1, 0x55, 0x13, 0x01, 0xe1, 0x30, 0x34, ++ 0x49, 0x89, 0xa1, 0xd4, 0x62, 0xd4, 0x16, 0x45, ++ 0x05, 0xf6, 0x39, 0x39, 0x33, 0x45, 0x0c, 0x67, ++ 0xbc, 0x6d, 0x39, 0xd8, 0xf5, 0x16, 0x09, 0x07, ++ 0xca, 0xbc, 0x25, 0x1b, 0x73, 0x79, 0x25, 0xa1, ++ 0xcf, 0x21, 0xe5, 0xc6, 0xaa, 0x57, 0x81, 0xb7, ++ 0x76, 0x9f, 0x6a, 0x2a, 0x58, 0x3d, 0x97, 0xcc, ++ 0xe0, 0x08, 0xc0, 0xf8, 0xb6, 0xad, 0xd5, 0xf0, ++ 0xb2, 0xbd, 0x80, 0xbe, 0xe6, 0x02, 0x37, 0xaa, ++ 0x39, 0xbb, 0x20, 0x71, 0x9f, 0xe7, 0x57, 0x49, ++ 0xf4, 0xbc, 0x4e, 0x42, 0x46, 0x6e, 0xf5, 0xa8, ++ 0x61, 0xae, 0x3a, 0x92, 0x39, 0x5c, 0x7d, 0x85, ++ 0x8d, 0x43, 0x0b, 0xfe, 0x38, 0x04, 0x0f, 0x44, ++ 0x5e, 0xa9, 0x3f, 0xa2, 0x95, 0x8b, 0x50, 0x35, ++ 0x39, 0x80, 0x0f, 0xfa, 0x5c, 0xe5, 0xf8, 0xcf, ++ 0x51, 0xfa, 0x81, 0x71, 0xa9, 0x1f, 0x36, 0xcb, ++ 0x4f, 0x45, 0x75, 0xe8, 0xde, 0x6b, 0x4d, 0x3f, ++ 0x09, 0x6e, 0xe1, 0x40, 0xb9, 0x38, 0xfd, 0x2f, ++ 0x50, 0xee, 0x13, 0xf0, 0xd0, 0x50, 0x22, 0x2e, ++ 0x2a, 0x72, 0xb0, 0xa3, 0x06, 0x9f, 0xf3, 0xa6, ++ 0x73, 0x8e, 0x82, 0xc8, 0x70, 0x90, 0xca, 0xa5, ++ 0xae, 0xd4, 0xfc, 0xbe, 0x88, 0x2c, 0x49, 0x64, ++ 0x6a, 0xa2, 0x50, 0xb9, 0x8f, 0x12, 0xf8, 0x3c, ++ 0x8d, 0x52, 0x81, 0x13, 0x61, 0x4a, 0x29, 0xe7}, ++ .msg_len = 256, ++ // sig is decrypted message ++ .sig = { 0x00 }, ++ .sig_len = 0, ++ }, ++ { // 2 - bad, max ++ .mod = {0xc8, 0xcc, 0x83, 0x97, 0x14, 0x09, 0x8d, 0xa5, ++ 0x6c, 0xaa, 0x23, 0x64, 0x0f, 0x93, 0xdc, 0x89, ++ 0x97, 0xc1, 0x63, 0x72, 0x96, 0x8f, 0xc1, 0xb0, ++ 0xc6, 0xdf, 0x51, 0x13, 0xc1, 0xc9, 0x4e, 0x8b, ++ 0x21, 0xe4, 0x8a, 0xd2, 0x29, 0x7e, 0x65, 0x41, ++ 0x90, 0x11, 0xb4, 0xe6, 0xd8, 0xf5, 0xe7, 0x3b, ++ 0x1b, 0x78, 0xb2, 0x57, 0x40, 0x03, 0x21, 0xd1, ++ 0xef, 0x6b, 0x60, 0x2d, 0x4e, 0xc8, 0xce, 0x8d, ++ 0x14, 0x1c, 0x94, 0x90, 0x5e, 0xb4, 0xad, 0x30, ++ 0x66, 0x39, 0xa4, 0x92, 0x06, 0x53, 0x4b, 0x6e, ++ 0x7f, 0x26, 0x07, 0x42, 0x3e, 0x97, 0xdf, 0xfd, ++ 0x13, 0x3c, 0x88, 0xd7, 0x21, 0x39, 0x9d, 0xef, ++ 0xbc, 0x7e, 0x96, 0xcc, 0xdc, 0xbd, 0x7f, 0x3a, ++ 0xae, 0x1f, 0xe8, 0x92, 0x71, 0x2b, 0xfb, 0x49, ++ 0x29, 0x81, 0x7d, 0x51, 0x16, 0x66, 0x44, 0x0a, ++ 0x1f, 0xac, 0xb7, 0xa2, 0x08, 0xf5, 0xea, 0x16, ++ 0x59, 0x10, 0xad, 0xd8, 0xa3, 0xf2, 0xd4, 0x97, ++ 0x20, 0x23, 0x60, 0xcc, 0xb6, 0x32, 0x02, 0x4f, ++ 0x0d, 0x07, 0x16, 0x9c, 0x19, 0x18, 0xf3, 0x16, ++ 0xf7, 0x94, 0xb1, 0x43, 0xae, 0xf5, 0x4e, 0xc8, ++ 0x75, 0x22, 0xa4, 0xc0, 0x29, 0x78, 0xf9, 0x68, ++ 0x99, 0x80, 0xbf, 0xfb, 0xf6, 0x49, 0xc3, 0x07, ++ 0xe8, 0x18, 0x19, 0xbf, 0xf8, 0x84, 0x09, 0x63, ++ 0x8d, 0x48, 0xbd, 0x94, 0xbe, 0x15, 0x2b, 0x59, ++ 0xff, 0x64, 0x9f, 0xa0, 0xbd, 0x62, 0x9d, 0x0f, ++ 0xfa, 0x18, 0x13, 0xc3, 0xab, 0xf4, 0xb5, 0x6b, ++ 0xd3, 0xc2, 0xea, 0x54, 0x65, 0xdf, 0xfa, 0x14, ++ 0x58, 0x92, 0x92, 0xa9, 0xd8, 0xa2, 0x4a, 0xd2, ++ 0x6b, 0xe7, 0xee, 0x05, 0x10, 0x74, 0x1b, 0x63, ++ 0x82, 0xd4, 0x3c, 0x83, 0xd5, 0xbf, 0xa4, 0x0a, ++ 0x46, 0x61, 0x3d, 0x06, 0x2b, 0xe4, 0x45, 0x51, ++ 0x7d, 0xbc, 0xaf, 0x0c, 0xb4, 0xe1, 0xa7, 0x69}, ++ .mod_len = 256, ++ .pub_exp = {0x01, 0x00, 0x01}, ++ .pubexp_len = 3, ++ .priv_exp = {0x14, 0x55, 0x01, 0x0e, 0x0f, 0x2d, 0x58, 0x76, ++ 0x63, 0xa6, 0x66, 0xa6, 0xff, 0x1c, 0xcd, 0xbb, ++ 0xf0, 0xed, 0xd8, 0x10, 0x06, 0x46, 0xd0, 0x2a, ++ 0x02, 0x39, 0x22, 0x90, 0x89, 0x92, 0xc4, 0xad, ++ 0x39, 0xe5, 0x56, 0x59, 0x29, 0x72, 0x6e, 0xf6, ++ 0x50, 0x8c, 0x3a, 0x71, 0x15, 0x8e, 0xf0, 0xb6, ++ 0xff, 0x75, 0x1d, 0x39, 0xd0, 0x75, 0x80, 0xbb, ++ 0x2d, 0x2f, 0x06, 0x32, 0x10, 0x44, 0x2d, 0x06, ++ 0x03, 0xff, 0x50, 0xdb, 0xbd, 0x7b, 0x35, 0xfe, ++ 0x2c, 0x9b, 0xb1, 0x9a, 0x47, 0xa1, 0xaf, 0x85, ++ 0xa4, 0xc2, 0x49, 0x01, 0xe0, 0x2c, 0xa8, 0xb5, ++ 0x8b, 0x79, 0x19, 0xb2, 0x0e, 0xdf, 0x32, 0xaa, ++ 0xcf, 0xbf, 0x51, 0xad, 0xb4, 0xbc, 0x4b, 0x61, ++ 0xb9, 0xb7, 0xe9, 0x68, 0xca, 0xa4, 0xd5, 0x70, ++ 0xf7, 0x0e, 0xf1, 0x8d, 0x80, 0x63, 0x22, 0x88, ++ 0x93, 0xe4, 0x7d, 0x43, 0x9e, 0xfc, 0xa7, 0x93, ++ 0x25, 0x9b, 0xcf, 0x2c, 0xd1, 0x08, 0xa3, 0xd8, ++ 0x68, 0x8c, 0xdf, 0x07, 0x8e, 0x7a, 0xc7, 0x99, ++ 0x96, 0x9f, 0x23, 0x39, 0xd2, 0xc1, 0xf5, 0x22, ++ 0xb9, 0x69, 0x68, 0x46, 0x29, 0xa9, 0x33, 0xba, ++ 0xae, 0xc2, 0x68, 0x16, 0x25, 0xea, 0xb8, 0x4f, ++ 0x4e, 0x56, 0xf4, 0x44, 0x7e, 0x9d, 0x88, 0xfb, ++ 0x9a, 0x19, 0x9c, 0xf7, 0x10, 0x23, 0xe0, 0xe2, ++ 0x57, 0xb1, 0x44, 0x41, 0xb3, 0x3c, 0x84, 0xd3, ++ 0xbc, 0x67, 0xca, 0x80, 0x31, 0xd2, 0x61, 0x26, ++ 0x18, 0x10, 0x3a, 0x7a, 0x0a, 0x40, 0x84, 0x42, ++ 0x62, 0xf7, 0x5d, 0x88, 0x90, 0xcd, 0x61, 0x6e, ++ 0x51, 0xf9, 0x03, 0x54, 0x88, 0xfd, 0x6e, 0x09, ++ 0x9d, 0xe8, 0xff, 0x6d, 0x65, 0xa4, 0xff, 0x11, ++ 0x82, 0x54, 0x80, 0x7c, 0x9f, 0x58, 0xd2, 0xfb, ++ 0xba, 0x8b, 0xa1, 0x51, 0xdc, 0x8c, 0x68, 0xbe, ++ 0x34, 0x9c, 0x97, 0x7a, 0x20, 0x4e, 0x04, 0xc1}, ++ .privexp_len = 256, ++ .prime1 = {0xf8, 0xf5, 0xad, 0x6b, 0xa8, 0x28, 0x93, 0x1b, ++ 0xea, 0x45, 0x9b, 0x8a, 0x3f, 0x6d, 0xc0, 0x41, ++ 0xd2, 0x34, 0x82, 0x40, 0x9c, 0x25, 0x71, 0xe9, ++ 0x63, 0xf3, 0x1f, 0x74, 0x86, 0x02, 0xa2, 0x56, ++ 0x37, 0x1b, 0x38, 0x83, 0xed, 0x45, 0x9e, 0xcf, ++ 0x97, 0x05, 0x26, 0x45, 0x9e, 0xdd, 0x16, 0xe0, ++ 0x55, 0x22, 0xf5, 0xa4, 0x5d, 0x94, 0x75, 0x1b, ++ 0x2e, 0xc2, 0xda, 0xf2, 0x72, 0xc7, 0xf8, 0x81, ++ 0x6a, 0x52, 0xc0, 0x0d, 0x18, 0x08, 0x01, 0x71, ++ 0x63, 0x4d, 0xa8, 0x99, 0xd7, 0x97, 0x32, 0x22, ++ 0xf5, 0x1b, 0x93, 0x76, 0x30, 0x54, 0x86, 0x96, ++ 0xa9, 0xf7, 0xd8, 0xc2, 0x4a, 0x59, 0x49, 0x7c, ++ 0x1e, 0xfc, 0xd4, 0x55, 0xcf, 0xb9, 0x7e, 0xe8, ++ 0x6d, 0x2b, 0x6d, 0x34, 0x97, 0x2b, 0x33, 0x2f, ++ 0xda, 0x30, 0x3f, 0x04, 0x99, 0x9b, 0x4e, 0xb6, ++ 0xb5, 0xcc, 0x0b, 0xb3, 0x3e, 0x77, 0x61, 0xdd}, ++ .prime1_len = 128, ++ .prime2 = {0xce, 0x7a, 0x2e, 0x3b, 0x49, 0xa9, 0x0b, 0x96, ++ 0x33, 0x0a, 0x12, 0xdc, 0x68, 0x2b, 0xdf, 0xbd, ++ 0xfb, 0xae, 0x8d, 0xd6, 0xdc, 0x03, 0xb6, 0x14, ++ 0x7a, 0xef, 0xbd, 0x57, 0x57, 0x43, 0xf0, 0xf6, ++ 0xda, 0x4d, 0x86, 0x23, 0x50, 0x61, 0xb7, 0x1a, ++ 0xfd, 0x9c, 0xad, 0x2d, 0x34, 0x02, 0x5e, 0x56, ++ 0xac, 0x86, 0xb0, 0xf7, 0x74, 0x3e, 0xb3, 0x5e, ++ 0x1a, 0xcb, 0xca, 0x23, 0x78, 0x95, 0x42, 0x44, ++ 0x65, 0xb7, 0x06, 0xed, 0x22, 0x17, 0x5e, 0x57, ++ 0x18, 0xc8, 0xc7, 0x0b, 0x67, 0x03, 0xea, 0x8f, ++ 0x6b, 0x51, 0x0f, 0x94, 0x5b, 0xe4, 0x8e, 0x5a, ++ 0x36, 0xbb, 0x3c, 0x3c, 0x91, 0x73, 0x2b, 0x58, ++ 0x9d, 0xfc, 0x05, 0xd7, 0x2d, 0x80, 0x90, 0x31, ++ 0x94, 0x45, 0x2b, 0xda, 0x21, 0x34, 0x86, 0x47, ++ 0xec, 0x72, 0x94, 0x3f, 0x11, 0xa8, 0x46, 0xe6, ++ 0x2f, 0xae, 0xbe, 0x8e, 0xb5, 0x36, 0xb0, 0xfd}, ++ .prime2_len = 128, ++ .exp1 = {0x76, 0xfe, 0x15, 0xf1, 0x8a, 0xe2, 0x39, 0xcd, ++ 0xf1, 0xdf, 0x6b, 0x44, 0x5c, 0xa4, 0xbc, 0x6b, ++ 0xb9, 0x68, 0xd7, 0x88, 0xc2, 0x19, 0x33, 0xa4, ++ 0xf5, 0xdc, 0xd2, 0x80, 0x03, 0x3d, 0x67, 0x12, ++ 0x06, 0x2c, 0xc0, 0x8a, 0x6d, 0xf2, 0x04, 0xc1, ++ 0xfb, 0xd0, 0xbe, 0x46, 0x30, 0x74, 0x43, 0xe6, ++ 0xdd, 0x4a, 0x64, 0x56, 0x37, 0x54, 0x29, 0xd4, ++ 0xe0, 0x38, 0xca, 0x25, 0x6f, 0xaf, 0x1c, 0x9b, ++ 0xde, 0x91, 0xc6, 0xb1, 0x7b, 0x76, 0xf8, 0x19, ++ 0x95, 0xf9, 0x1c, 0x48, 0xcb, 0xbe, 0xbc, 0x7b, ++ 0xf0, 0xe3, 0x49, 0x4c, 0x08, 0x35, 0x9e, 0x4e, ++ 0x8c, 0xd6, 0xa5, 0x87, 0xd7, 0xb9, 0x6d, 0x62, ++ 0x21, 0xfd, 0x7e, 0x0f, 0xb5, 0xc5, 0x57, 0x5f, ++ 0x08, 0x2e, 0xe5, 0x77, 0x69, 0x79, 0x80, 0x71, ++ 0xb2, 0xbb, 0xb4, 0xa3, 0x22, 0x38, 0x15, 0x1b, ++ 0x47, 0x31, 0x4b, 0xb6, 0x54, 0x79, 0x03, 0x11}, ++ .exp1_len = 128, ++ .exp2 = {0x99, 0x88, 0x48, 0xb0, 0x55, 0x49, 0x9a, 0x10, ++ 0x09, 0xcb, 0xc7, 0xd2, 0x94, 0xb3, 0x6b, 0x1f, ++ 0xfd, 0xf2, 0x02, 0x0e, 0x6e, 0x73, 0x64, 0x05, ++ 0x3e, 0x94, 0xde, 0x1a, 0x00, 0x0d, 0xc9, 0x34, ++ 0x05, 0x87, 0xf7, 0xe2, 0x72, 0x76, 0xf6, 0x8c, ++ 0xdf, 0x60, 0x8d, 0x75, 0x3b, 0x63, 0x37, 0x7b, ++ 0x03, 0xb6, 0xf4, 0x08, 0x4d, 0x2c, 0x02, 0x7c, ++ 0x4b, 0x38, 0x96, 0x0a, 0x62, 0x33, 0xba, 0x9e, ++ 0xd9, 0x73, 0x8b, 0x76, 0xf1, 0x0e, 0xa7, 0x5b, ++ 0xe4, 0x56, 0x07, 0x8b, 0xf7, 0x01, 0xf6, 0x7c, ++ 0xc6, 0xb3, 0xf3, 0xfd, 0xc1, 0x86, 0xe6, 0x43, ++ 0x36, 0xc7, 0x6b, 0x37, 0x2e, 0x80, 0x91, 0x0e, ++ 0xc8, 0x0b, 0x0a, 0xdc, 0xc2, 0x3d, 0x02, 0xfb, ++ 0x9a, 0xe1, 0x04, 0x86, 0xa2, 0x82, 0x48, 0x07, ++ 0x5b, 0x4e, 0xa7, 0xe5, 0x6d, 0xdf, 0xcf, 0x38, ++ 0x82, 0xe4, 0x51, 0x56, 0x14, 0x71, 0xa2, 0x91}, ++ .exp2_len = 128, ++ .coef = {0x64, 0x3b, 0xf7, 0x46, 0x42, 0x9f, 0x7d, 0x83, ++ 0x66, 0x7a, 0x06, 0x53, 0x02, 0x13, 0x47, 0xef, ++ 0xbf, 0xc0, 0x5e, 0x63, 0x51, 0xf8, 0x21, 0xa9, ++ 0xde, 0xbb, 0x60, 0xe0, 0xec, 0xcd, 0xe5, 0x00, ++ 0x5a, 0xd9, 0xe9, 0xec, 0x31, 0xe5, 0x58, 0xf7, ++ 0xe9, 0x2c, 0x29, 0x32, 0x8e, 0x74, 0x56, 0x9d, ++ 0x7c, 0xef, 0x7c, 0x74, 0xca, 0xbc, 0x2b, 0x35, ++ 0x5e, 0xd4, 0x01, 0xa1, 0xa0, 0x91, 0x4b, 0x4e, ++ 0x3c, 0xbb, 0x06, 0x48, 0x4e, 0x58, 0x19, 0x60, ++ 0x51, 0x16, 0x9e, 0xd1, 0x4c, 0xaa, 0x2e, 0xfa, ++ 0x6e, 0xa0, 0x44, 0xe0, 0x54, 0xd2, 0x61, 0x44, ++ 0xcc, 0x16, 0x29, 0xc5, 0x50, 0x10, 0x55, 0x8a, ++ 0x04, 0xe1, 0x33, 0xf4, 0x4b, 0x7c, 0x24, 0x4d, ++ 0xac, 0x25, 0xbf, 0x91, 0x3c, 0x57, 0xb8, 0x90, ++ 0xee, 0x49, 0xf5, 0x48, 0x25, 0x9c, 0xd6, 0x34, ++ 0x04, 0xfe, 0xf6, 0x85, 0x9d, 0xcf, 0x97, 0x5a}, ++ .coef_len = 128, ++ // msg is encrypted message ++ .msg = {0x48, 0xcc, 0xea, 0xb1, 0x0f, 0x39, 0xa4, 0xdb, ++ 0x32, 0xf6, 0x00, 0x74, 0xfe, 0xea, 0x47, 0x3c, ++ 0xbc, 0xdb, 0x7a, 0xcc, 0xf9, 0x2e, 0x15, 0x04, ++ 0x17, 0xf7, 0x6b, 0x44, 0x75, 0x6b, 0x19, 0x0e, ++ 0x84, 0x3e, 0x79, 0xec, 0x12, 0xaa, 0x85, 0x08, ++ 0x3a, 0x21, 0xf5, 0x43, 0x7e, 0x7b, 0xad, 0x0a, ++ 0x60, 0x48, 0x2e, 0x60, 0x11, 0x98, 0xf9, 0xd8, ++ 0x69, 0x23, 0x23, 0x9c, 0x87, 0x86, 0xee, 0x72, ++ 0x82, 0x85, 0xaf, 0xd0, 0x93, 0x7f, 0x7d, 0xde, ++ 0x12, 0x71, 0x7f, 0x28, 0x38, 0x98, 0x43, 0xd7, ++ 0x37, 0x59, 0x12, 0xb0, 0x7b, 0x99, 0x1f, 0x4f, ++ 0xdb, 0x01, 0x90, 0xfc, 0xed, 0x8b, 0xa6, 0x65, ++ 0x31, 0x43, 0x67, 0xe8, 0xc5, 0xf9, 0xd2, 0x98, ++ 0x1d, 0x0f, 0x51, 0x28, 0xfe, 0xeb, 0x46, 0xcb, ++ 0x50, 0xfc, 0x23, 0x7e, 0x64, 0x43, 0x8a, 0x86, ++ 0xdf, 0x19, 0x8d, 0xd0, 0x20, 0x93, 0x64, 0xae, ++ 0x3a, 0x84, 0x2d, 0x77, 0x53, 0x2b, 0x66, 0xb7, ++ 0xef, 0x26, 0x3b, 0x83, 0xb1, 0x54, 0x1e, 0xd6, ++ 0x71, 0xb1, 0x20, 0xdf, 0xd6, 0x60, 0x46, 0x2e, ++ 0x21, 0x07, 0xa4, 0xee, 0x7b, 0x96, 0x4e, 0x73, ++ 0x4a, 0x7b, 0xd6, 0x8d, 0x90, 0xdd, 0xa6, 0x17, ++ 0x70, 0x65, 0x8a, 0x3c, 0x24, 0x29, 0x48, 0x53, ++ 0x2d, 0xa3, 0x26, 0x48, 0x68, 0x7e, 0x03, 0x18, ++ 0x28, 0x64, 0x73, 0xf6, 0x75, 0xb4, 0x12, 0xd6, ++ 0x46, 0x8f, 0x01, 0x3f, 0x14, 0xd7, 0x60, 0xa3, ++ 0x58, 0xdf, 0xca, 0xd3, 0xcd, 0xa2, 0xaf, 0xee, ++ 0xc5, 0xe2, 0x68, 0xa3, 0x7d, 0x25, 0x0c, 0x37, ++ 0xf7, 0x22, 0xf4, 0x68, 0xa7, 0x0d, 0xfd, 0x92, ++ 0xd7, 0x29, 0x4c, 0x3c, 0x1e, 0xe1, 0xe7, 0xf8, ++ 0x84, 0x3b, 0x7d, 0x16, 0xf9, 0xf3, 0x7e, 0xf3, ++ 0x57, 0x48, 0xc3, 0xae, 0x93, 0xaa, 0x15, 0x5c, ++ 0xdc, 0xdf, 0xeb, 0x4e, 0x78, 0x56, 0x73, 0x03}, ++ .msg_len = 256, ++ // sig is decrypted message ++ .sig = { 0x22, 0xd8, 0x50, 0x13, 0x7b, 0x9e, 0xeb, 0xe0, ++ 0x92, 0xb2, 0x4f, 0x60, 0x2d, 0xc5, 0xbb, 0x79, ++ 0x18, 0xc1, 0x6b, 0xd8, 0x9d, 0xdb, 0xf2, 0x04, ++ 0x67, 0xb1, 0x19, 0xd2, 0x05, 0xf9, 0xc2, 0xe4, ++ 0xbd, 0x7d, 0x25, 0x92, 0xcf, 0x1e, 0x53, 0x21, ++ 0x06, 0xe0, 0xf3, 0x35, 0x57, 0x56, 0x59, 0x23, ++ 0xc7, 0x3a, 0x02, 0xd4, 0xf0, 0x9c, 0x0c, 0x22, ++ 0xbe, 0xa8, 0x91, 0x48, 0x18, 0x3e, 0x60, 0x31, ++ 0x7f, 0x70, 0x28, 0xb3, 0xaa, 0x1f, 0x26, 0x1f, ++ 0x91, 0xc9, 0x79, 0x39, 0x31, 0x01, 0xd7, 0xe1, ++ 0x5f, 0x40, 0x67, 0xe6, 0x39, 0x79, 0xb3, 0x27, ++ 0x51, 0x65, 0x8e, 0xf7, 0x69, 0x61, 0x0f, 0xe9, ++ 0x7c, 0xf9, 0xce, 0xf3, 0x27, 0x8b, 0x31, 0x17, ++ 0xd3, 0x84, 0x05, 0x1c, 0x3b, 0x1d, 0x82, 0xc2, ++ 0x51, 0xc2, 0x30, 0x54, 0x18, 0xc8, 0xf6, 0x84, ++ 0x05, 0x30, 0xe6, 0x31, 0xaa, 0xd6, 0x3e, 0x70, ++ 0xe2, 0x0e, 0x02, 0x5b, 0xcd, 0x8e, 0xfb, 0x54, ++ 0xc9, 0x2e, 0xc6, 0xd3, 0xb1, 0x06, 0xa2, 0xf8, ++ 0xe6, 0x4e, 0xef, 0xf7, 0xd3, 0x84, 0x95, 0xb0, ++ 0xfc, 0x50, 0xc9, 0x71, 0x38, 0xaf, 0x4b, 0x1c, ++ 0x0a, 0x67, 0xa1, 0xc4, 0xe2, 0x7b, 0x07, 0x7b, ++ 0x84, 0x39, 0x33, 0x2e, 0xdf, 0xa8, 0x60, 0x8d, ++ 0xfe, 0xae, 0x65, 0x3c, 0xd6, 0xa6, 0x28, 0xac, ++ 0x55, 0x03, 0x95, 0xf7, 0xe7, 0x43, 0x90, 0xe4, ++ 0x2c, 0x11, 0x68, 0x22, 0x34, 0x87, 0x09, 0x25, ++ 0xee, 0xaa, 0x1f, 0xa7, 0x1b, 0x76, 0xcf, 0x1f, ++ 0x2e, 0xe3, 0xbd, 0xa6, 0x9f, 0x67, 0x17, 0x03, ++ 0x3f, 0xf8, 0xb7, 0xc9, 0x5c, 0x97, 0x99, 0xe7, ++ 0xa3, 0xbe, 0xa5, 0xe7, 0xe4, 0xa1, 0xc3, 0x59, ++ 0x77, 0x2f, 0xb6, 0xb1, 0xc6, 0xe6, 0xc5, 0x16, ++ 0x66, 0x1d, 0xfe, 0x30, 0xc3}, ++ .sig_len = 245, ++ }, ++ { // 3 bad, prf ++ .mod = {0xc8, 0xcc, 0x83, 0x97, 0x14, 0x09, 0x8d, 0xa5, ++ 0x6c, 0xaa, 0x23, 0x64, 0x0f, 0x93, 0xdc, 0x89, ++ 0x97, 0xc1, 0x63, 0x72, 0x96, 0x8f, 0xc1, 0xb0, ++ 0xc6, 0xdf, 0x51, 0x13, 0xc1, 0xc9, 0x4e, 0x8b, ++ 0x21, 0xe4, 0x8a, 0xd2, 0x29, 0x7e, 0x65, 0x41, ++ 0x90, 0x11, 0xb4, 0xe6, 0xd8, 0xf5, 0xe7, 0x3b, ++ 0x1b, 0x78, 0xb2, 0x57, 0x40, 0x03, 0x21, 0xd1, ++ 0xef, 0x6b, 0x60, 0x2d, 0x4e, 0xc8, 0xce, 0x8d, ++ 0x14, 0x1c, 0x94, 0x90, 0x5e, 0xb4, 0xad, 0x30, ++ 0x66, 0x39, 0xa4, 0x92, 0x06, 0x53, 0x4b, 0x6e, ++ 0x7f, 0x26, 0x07, 0x42, 0x3e, 0x97, 0xdf, 0xfd, ++ 0x13, 0x3c, 0x88, 0xd7, 0x21, 0x39, 0x9d, 0xef, ++ 0xbc, 0x7e, 0x96, 0xcc, 0xdc, 0xbd, 0x7f, 0x3a, ++ 0xae, 0x1f, 0xe8, 0x92, 0x71, 0x2b, 0xfb, 0x49, ++ 0x29, 0x81, 0x7d, 0x51, 0x16, 0x66, 0x44, 0x0a, ++ 0x1f, 0xac, 0xb7, 0xa2, 0x08, 0xf5, 0xea, 0x16, ++ 0x59, 0x10, 0xad, 0xd8, 0xa3, 0xf2, 0xd4, 0x97, ++ 0x20, 0x23, 0x60, 0xcc, 0xb6, 0x32, 0x02, 0x4f, ++ 0x0d, 0x07, 0x16, 0x9c, 0x19, 0x18, 0xf3, 0x16, ++ 0xf7, 0x94, 0xb1, 0x43, 0xae, 0xf5, 0x4e, 0xc8, ++ 0x75, 0x22, 0xa4, 0xc0, 0x29, 0x78, 0xf9, 0x68, ++ 0x99, 0x80, 0xbf, 0xfb, 0xf6, 0x49, 0xc3, 0x07, ++ 0xe8, 0x18, 0x19, 0xbf, 0xf8, 0x84, 0x09, 0x63, ++ 0x8d, 0x48, 0xbd, 0x94, 0xbe, 0x15, 0x2b, 0x59, ++ 0xff, 0x64, 0x9f, 0xa0, 0xbd, 0x62, 0x9d, 0x0f, ++ 0xfa, 0x18, 0x13, 0xc3, 0xab, 0xf4, 0xb5, 0x6b, ++ 0xd3, 0xc2, 0xea, 0x54, 0x65, 0xdf, 0xfa, 0x14, ++ 0x58, 0x92, 0x92, 0xa9, 0xd8, 0xa2, 0x4a, 0xd2, ++ 0x6b, 0xe7, 0xee, 0x05, 0x10, 0x74, 0x1b, 0x63, ++ 0x82, 0xd4, 0x3c, 0x83, 0xd5, 0xbf, 0xa4, 0x0a, ++ 0x46, 0x61, 0x3d, 0x06, 0x2b, 0xe4, 0x45, 0x51, ++ 0x7d, 0xbc, 0xaf, 0x0c, 0xb4, 0xe1, 0xa7, 0x69}, ++ .mod_len = 256, ++ .pub_exp = {0x01, 0x00, 0x01}, ++ .pubexp_len = 3, ++ .priv_exp = {0x14, 0x55, 0x01, 0x0e, 0x0f, 0x2d, 0x58, 0x76, ++ 0x63, 0xa6, 0x66, 0xa6, 0xff, 0x1c, 0xcd, 0xbb, ++ 0xf0, 0xed, 0xd8, 0x10, 0x06, 0x46, 0xd0, 0x2a, ++ 0x02, 0x39, 0x22, 0x90, 0x89, 0x92, 0xc4, 0xad, ++ 0x39, 0xe5, 0x56, 0x59, 0x29, 0x72, 0x6e, 0xf6, ++ 0x50, 0x8c, 0x3a, 0x71, 0x15, 0x8e, 0xf0, 0xb6, ++ 0xff, 0x75, 0x1d, 0x39, 0xd0, 0x75, 0x80, 0xbb, ++ 0x2d, 0x2f, 0x06, 0x32, 0x10, 0x44, 0x2d, 0x06, ++ 0x03, 0xff, 0x50, 0xdb, 0xbd, 0x7b, 0x35, 0xfe, ++ 0x2c, 0x9b, 0xb1, 0x9a, 0x47, 0xa1, 0xaf, 0x85, ++ 0xa4, 0xc2, 0x49, 0x01, 0xe0, 0x2c, 0xa8, 0xb5, ++ 0x8b, 0x79, 0x19, 0xb2, 0x0e, 0xdf, 0x32, 0xaa, ++ 0xcf, 0xbf, 0x51, 0xad, 0xb4, 0xbc, 0x4b, 0x61, ++ 0xb9, 0xb7, 0xe9, 0x68, 0xca, 0xa4, 0xd5, 0x70, ++ 0xf7, 0x0e, 0xf1, 0x8d, 0x80, 0x63, 0x22, 0x88, ++ 0x93, 0xe4, 0x7d, 0x43, 0x9e, 0xfc, 0xa7, 0x93, ++ 0x25, 0x9b, 0xcf, 0x2c, 0xd1, 0x08, 0xa3, 0xd8, ++ 0x68, 0x8c, 0xdf, 0x07, 0x8e, 0x7a, 0xc7, 0x99, ++ 0x96, 0x9f, 0x23, 0x39, 0xd2, 0xc1, 0xf5, 0x22, ++ 0xb9, 0x69, 0x68, 0x46, 0x29, 0xa9, 0x33, 0xba, ++ 0xae, 0xc2, 0x68, 0x16, 0x25, 0xea, 0xb8, 0x4f, ++ 0x4e, 0x56, 0xf4, 0x44, 0x7e, 0x9d, 0x88, 0xfb, ++ 0x9a, 0x19, 0x9c, 0xf7, 0x10, 0x23, 0xe0, 0xe2, ++ 0x57, 0xb1, 0x44, 0x41, 0xb3, 0x3c, 0x84, 0xd3, ++ 0xbc, 0x67, 0xca, 0x80, 0x31, 0xd2, 0x61, 0x26, ++ 0x18, 0x10, 0x3a, 0x7a, 0x0a, 0x40, 0x84, 0x42, ++ 0x62, 0xf7, 0x5d, 0x88, 0x90, 0xcd, 0x61, 0x6e, ++ 0x51, 0xf9, 0x03, 0x54, 0x88, 0xfd, 0x6e, 0x09, ++ 0x9d, 0xe8, 0xff, 0x6d, 0x65, 0xa4, 0xff, 0x11, ++ 0x82, 0x54, 0x80, 0x7c, 0x9f, 0x58, 0xd2, 0xfb, ++ 0xba, 0x8b, 0xa1, 0x51, 0xdc, 0x8c, 0x68, 0xbe, ++ 0x34, 0x9c, 0x97, 0x7a, 0x20, 0x4e, 0x04, 0xc1}, ++ .privexp_len = 256, ++ .prime1 = {0xf8, 0xf5, 0xad, 0x6b, 0xa8, 0x28, 0x93, 0x1b, ++ 0xea, 0x45, 0x9b, 0x8a, 0x3f, 0x6d, 0xc0, 0x41, ++ 0xd2, 0x34, 0x82, 0x40, 0x9c, 0x25, 0x71, 0xe9, ++ 0x63, 0xf3, 0x1f, 0x74, 0x86, 0x02, 0xa2, 0x56, ++ 0x37, 0x1b, 0x38, 0x83, 0xed, 0x45, 0x9e, 0xcf, ++ 0x97, 0x05, 0x26, 0x45, 0x9e, 0xdd, 0x16, 0xe0, ++ 0x55, 0x22, 0xf5, 0xa4, 0x5d, 0x94, 0x75, 0x1b, ++ 0x2e, 0xc2, 0xda, 0xf2, 0x72, 0xc7, 0xf8, 0x81, ++ 0x6a, 0x52, 0xc0, 0x0d, 0x18, 0x08, 0x01, 0x71, ++ 0x63, 0x4d, 0xa8, 0x99, 0xd7, 0x97, 0x32, 0x22, ++ 0xf5, 0x1b, 0x93, 0x76, 0x30, 0x54, 0x86, 0x96, ++ 0xa9, 0xf7, 0xd8, 0xc2, 0x4a, 0x59, 0x49, 0x7c, ++ 0x1e, 0xfc, 0xd4, 0x55, 0xcf, 0xb9, 0x7e, 0xe8, ++ 0x6d, 0x2b, 0x6d, 0x34, 0x97, 0x2b, 0x33, 0x2f, ++ 0xda, 0x30, 0x3f, 0x04, 0x99, 0x9b, 0x4e, 0xb6, ++ 0xb5, 0xcc, 0x0b, 0xb3, 0x3e, 0x77, 0x61, 0xdd}, ++ .prime1_len = 128, ++ .prime2 = {0xce, 0x7a, 0x2e, 0x3b, 0x49, 0xa9, 0x0b, 0x96, ++ 0x33, 0x0a, 0x12, 0xdc, 0x68, 0x2b, 0xdf, 0xbd, ++ 0xfb, 0xae, 0x8d, 0xd6, 0xdc, 0x03, 0xb6, 0x14, ++ 0x7a, 0xef, 0xbd, 0x57, 0x57, 0x43, 0xf0, 0xf6, ++ 0xda, 0x4d, 0x86, 0x23, 0x50, 0x61, 0xb7, 0x1a, ++ 0xfd, 0x9c, 0xad, 0x2d, 0x34, 0x02, 0x5e, 0x56, ++ 0xac, 0x86, 0xb0, 0xf7, 0x74, 0x3e, 0xb3, 0x5e, ++ 0x1a, 0xcb, 0xca, 0x23, 0x78, 0x95, 0x42, 0x44, ++ 0x65, 0xb7, 0x06, 0xed, 0x22, 0x17, 0x5e, 0x57, ++ 0x18, 0xc8, 0xc7, 0x0b, 0x67, 0x03, 0xea, 0x8f, ++ 0x6b, 0x51, 0x0f, 0x94, 0x5b, 0xe4, 0x8e, 0x5a, ++ 0x36, 0xbb, 0x3c, 0x3c, 0x91, 0x73, 0x2b, 0x58, ++ 0x9d, 0xfc, 0x05, 0xd7, 0x2d, 0x80, 0x90, 0x31, ++ 0x94, 0x45, 0x2b, 0xda, 0x21, 0x34, 0x86, 0x47, ++ 0xec, 0x72, 0x94, 0x3f, 0x11, 0xa8, 0x46, 0xe6, ++ 0x2f, 0xae, 0xbe, 0x8e, 0xb5, 0x36, 0xb0, 0xfd}, ++ .prime2_len = 128, ++ .exp1 = {0x76, 0xfe, 0x15, 0xf1, 0x8a, 0xe2, 0x39, 0xcd, ++ 0xf1, 0xdf, 0x6b, 0x44, 0x5c, 0xa4, 0xbc, 0x6b, ++ 0xb9, 0x68, 0xd7, 0x88, 0xc2, 0x19, 0x33, 0xa4, ++ 0xf5, 0xdc, 0xd2, 0x80, 0x03, 0x3d, 0x67, 0x12, ++ 0x06, 0x2c, 0xc0, 0x8a, 0x6d, 0xf2, 0x04, 0xc1, ++ 0xfb, 0xd0, 0xbe, 0x46, 0x30, 0x74, 0x43, 0xe6, ++ 0xdd, 0x4a, 0x64, 0x56, 0x37, 0x54, 0x29, 0xd4, ++ 0xe0, 0x38, 0xca, 0x25, 0x6f, 0xaf, 0x1c, 0x9b, ++ 0xde, 0x91, 0xc6, 0xb1, 0x7b, 0x76, 0xf8, 0x19, ++ 0x95, 0xf9, 0x1c, 0x48, 0xcb, 0xbe, 0xbc, 0x7b, ++ 0xf0, 0xe3, 0x49, 0x4c, 0x08, 0x35, 0x9e, 0x4e, ++ 0x8c, 0xd6, 0xa5, 0x87, 0xd7, 0xb9, 0x6d, 0x62, ++ 0x21, 0xfd, 0x7e, 0x0f, 0xb5, 0xc5, 0x57, 0x5f, ++ 0x08, 0x2e, 0xe5, 0x77, 0x69, 0x79, 0x80, 0x71, ++ 0xb2, 0xbb, 0xb4, 0xa3, 0x22, 0x38, 0x15, 0x1b, ++ 0x47, 0x31, 0x4b, 0xb6, 0x54, 0x79, 0x03, 0x11}, ++ .exp1_len = 128, ++ .exp2 = {0x99, 0x88, 0x48, 0xb0, 0x55, 0x49, 0x9a, 0x10, ++ 0x09, 0xcb, 0xc7, 0xd2, 0x94, 0xb3, 0x6b, 0x1f, ++ 0xfd, 0xf2, 0x02, 0x0e, 0x6e, 0x73, 0x64, 0x05, ++ 0x3e, 0x94, 0xde, 0x1a, 0x00, 0x0d, 0xc9, 0x34, ++ 0x05, 0x87, 0xf7, 0xe2, 0x72, 0x76, 0xf6, 0x8c, ++ 0xdf, 0x60, 0x8d, 0x75, 0x3b, 0x63, 0x37, 0x7b, ++ 0x03, 0xb6, 0xf4, 0x08, 0x4d, 0x2c, 0x02, 0x7c, ++ 0x4b, 0x38, 0x96, 0x0a, 0x62, 0x33, 0xba, 0x9e, ++ 0xd9, 0x73, 0x8b, 0x76, 0xf1, 0x0e, 0xa7, 0x5b, ++ 0xe4, 0x56, 0x07, 0x8b, 0xf7, 0x01, 0xf6, 0x7c, ++ 0xc6, 0xb3, 0xf3, 0xfd, 0xc1, 0x86, 0xe6, 0x43, ++ 0x36, 0xc7, 0x6b, 0x37, 0x2e, 0x80, 0x91, 0x0e, ++ 0xc8, 0x0b, 0x0a, 0xdc, 0xc2, 0x3d, 0x02, 0xfb, ++ 0x9a, 0xe1, 0x04, 0x86, 0xa2, 0x82, 0x48, 0x07, ++ 0x5b, 0x4e, 0xa7, 0xe5, 0x6d, 0xdf, 0xcf, 0x38, ++ 0x82, 0xe4, 0x51, 0x56, 0x14, 0x71, 0xa2, 0x91}, ++ .exp2_len = 128, ++ .coef = {0x64, 0x3b, 0xf7, 0x46, 0x42, 0x9f, 0x7d, 0x83, ++ 0x66, 0x7a, 0x06, 0x53, 0x02, 0x13, 0x47, 0xef, ++ 0xbf, 0xc0, 0x5e, 0x63, 0x51, 0xf8, 0x21, 0xa9, ++ 0xde, 0xbb, 0x60, 0xe0, 0xec, 0xcd, 0xe5, 0x00, ++ 0x5a, 0xd9, 0xe9, 0xec, 0x31, 0xe5, 0x58, 0xf7, ++ 0xe9, 0x2c, 0x29, 0x32, 0x8e, 0x74, 0x56, 0x9d, ++ 0x7c, 0xef, 0x7c, 0x74, 0xca, 0xbc, 0x2b, 0x35, ++ 0x5e, 0xd4, 0x01, 0xa1, 0xa0, 0x91, 0x4b, 0x4e, ++ 0x3c, 0xbb, 0x06, 0x48, 0x4e, 0x58, 0x19, 0x60, ++ 0x51, 0x16, 0x9e, 0xd1, 0x4c, 0xaa, 0x2e, 0xfa, ++ 0x6e, 0xa0, 0x44, 0xe0, 0x54, 0xd2, 0x61, 0x44, ++ 0xcc, 0x16, 0x29, 0xc5, 0x50, 0x10, 0x55, 0x8a, ++ 0x04, 0xe1, 0x33, 0xf4, 0x4b, 0x7c, 0x24, 0x4d, ++ 0xac, 0x25, 0xbf, 0x91, 0x3c, 0x57, 0xb8, 0x90, ++ 0xee, 0x49, 0xf5, 0x48, 0x25, 0x9c, 0xd6, 0x34, ++ 0x04, 0xfe, 0xf6, 0x85, 0x9d, 0xcf, 0x97, 0x5a}, ++ .coef_len = 128, ++ // msg is encrypted message ++ .msg = {0x14, 0x39, 0xe0, 0x8c, 0x3f, 0x84, 0xc1, 0xa7, ++ 0xfe, 0xc7, 0x4c, 0xe0, 0x76, 0x14, 0xb2, 0x0e, ++ 0x01, 0xf6, 0xfa, 0x4e, 0x8c, 0x2a, 0x6c, 0xff, ++ 0xdc, 0x35, 0x20, 0xd8, 0x88, 0x9e, 0x5d, 0x9a, ++ 0x95, 0x0c, 0x64, 0x25, 0x79, 0x8f, 0x85, 0xd4, ++ 0xbe, 0x38, 0xd3, 0x00, 0xea, 0x56, 0x95, 0xf1, ++ 0x3e, 0xcd, 0x4c, 0xb3, 0x89, 0xd1, 0xff, 0x5b, ++ 0x82, 0x48, 0x4b, 0x49, 0x4d, 0x62, 0x80, 0xab, ++ 0x7f, 0xa7, 0x8e, 0x64, 0x59, 0x33, 0x98, 0x1c, ++ 0xb9, 0x34, 0xcc, 0xe8, 0xbf, 0xcd, 0x11, 0x4c, ++ 0xc0, 0xe6, 0x81, 0x1e, 0xef, 0xa4, 0x7a, 0xae, ++ 0x20, 0xaf, 0x63, 0x8a, 0x1c, 0xd1, 0x63, 0xd2, ++ 0xd3, 0x36, 0x61, 0x86, 0xd0, 0xa0, 0x7d, 0xf0, ++ 0xc8, 0x1f, 0x6c, 0x9f, 0x31, 0x71, 0xcf, 0x35, ++ 0x61, 0x47, 0x2e, 0x98, 0xa6, 0x00, 0x6b, 0xf7, ++ 0x5d, 0xdb, 0x45, 0x7b, 0xed, 0x03, 0x6d, 0xcc, ++ 0xe1, 0x99, 0x36, 0x9d, 0xe7, 0xd9, 0x4e, 0xf2, ++ 0xc6, 0x8e, 0x84, 0x67, 0xee, 0x06, 0x04, 0xee, ++ 0xa2, 0xb3, 0x00, 0x94, 0x79, 0x16, 0x2a, 0x78, ++ 0x91, 0xba, 0x5c, 0x40, 0xca, 0xb1, 0x7f, 0x49, ++ 0xe1, 0xc4, 0x38, 0xcb, 0x6e, 0xae, 0xa4, 0xf7, ++ 0x6c, 0xe2, 0x3c, 0xce, 0x0e, 0x48, 0x3f, 0xf0, ++ 0xe9, 0x6f, 0xa7, 0x90, 0xea, 0x15, 0xbe, 0x67, ++ 0x67, 0x18, 0x14, 0x34, 0x2d, 0x0a, 0x23, 0xf4, ++ 0xa2, 0x02, 0x62, 0xb6, 0x18, 0x2e, 0x72, 0xf3, ++ 0xa6, 0x7c, 0xd2, 0x89, 0x71, 0x15, 0x03, 0xc8, ++ 0x55, 0x16, 0xa9, 0xed, 0x22, 0x54, 0x22, 0xf9, ++ 0x8b, 0x11, 0x6f, 0x1a, 0xb0, 0x80, 0xa8, 0x0a, ++ 0xbd, 0x6f, 0x02, 0x16, 0xdf, 0x88, 0xd8, 0xcf, ++ 0xd6, 0x7c, 0x13, 0x92, 0x43, 0xbe, 0x8d, 0xd7, ++ 0x85, 0x02, 0xa7, 0xaa, 0xf6, 0xbc, 0x99, 0xd7, ++ 0xda, 0x71, 0xbc, 0xdf, 0x62, 0x7e, 0x73, 0x54}, ++ .msg_len = 256, ++ // sig is decrypted message ++ .sig = { 0x0f, 0x9b}, ++ .sig_len = 2, ++ }, ++}; ++ ++#define NUM_OF_IMPLICIT_REJECTION_TESTSUITES 1 ++struct PUBLISHED_TEST_SUITE_INFO rsa_implicit_rejection_test_suites[] = { ++ { ++ .name = "RSA PKCS v1.5", ++ .tvcount = 4, ++ .tv = rsa_imp_rejection_tv, ++ .mech = {CKM_RSA_PKCS, 0, 0}, ++ }, ++}; +diff --git a/testcases/crypto/rsa_func.c b/testcases/crypto/rsa_func.c +index 2c9984d0..c092110e 100644 +--- a/testcases/crypto/rsa_func.c ++++ b/testcases/crypto/rsa_func.c +@@ -1963,6 +1963,164 @@ testcase_cleanup: + return rc; + } + ++CK_RV do_RSAImplicitRejection(struct PUBLISHED_TEST_SUITE_INFO *tsuite) ++{ ++ unsigned int i; ++ CK_BYTE decrypt[BIG_REQUEST]; ++ CK_ULONG decrypt_len; ++ CK_MECHANISM mech; ++ CK_OBJECT_HANDLE priv_key = CK_INVALID_HANDLE; ++ CK_SLOT_ID slot_id = SLOT_ID; ++ CK_SESSION_HANDLE session; ++ CK_FLAGS flags; ++ CK_BYTE user_pin[PKCS11_MAX_PIN_LEN]; ++ CK_ULONG user_pin_len; ++ CK_RV rc, loc_rc; ++ ++ char *s; ++ ++ // begin testsuite ++ testsuite_begin("%s Implicit Rejection.", tsuite->name); ++ testcase_rw_session(); ++ testcase_user_login(); ++ ++ if (!is_ica_token(slot_id) && !is_soft_token(slot_id)) { ++ testsuite_skip(tsuite->tvcount, ++ "Slot %u doesn't support Implicit Rejection", ++ (unsigned int) slot_id); ++ goto testcase_cleanup; ++ } ++ // skip tests if the slot doesn't support this mechanism ++ if (!mech_supported(slot_id, tsuite->mech.mechanism)) { ++ testsuite_skip(tsuite->tvcount, ++ "Slot %u doesn't support %s (0x%x)", ++ (unsigned int) slot_id, ++ mech_to_str(tsuite->mech.mechanism), ++ (unsigned int) tsuite->mech.mechanism); ++ goto testcase_cleanup; ++ } ++ ++ // iterate over test vectors ++ for (i = 0; i < tsuite->tvcount; i++) { ++ ++ // get public exponent from test vector ++ if (p11_ahex_dump(&s, tsuite->tv[i].pub_exp, ++ tsuite->tv[i].pubexp_len) == NULL) { ++ testcase_error("p11_ahex_dump() failed"); ++ rc = -1; ++ goto testcase_cleanup; ++ } ++ // begin testcase ++ testcase_begin("%s Implicit Rejection with test vector %u." ++ "\npubl_exp='%s', modbits=%lu, publ_exp_len=%lu.", ++ tsuite->name, i, s, ++ tsuite->tv[i].mod_len * 8, ++ tsuite->tv[i].pubexp_len); ++ ++ rc = CKR_OK; ++ ++ if (!keysize_supported(slot_id, tsuite->mech.mechanism, ++ tsuite->tv[i].mod_len * 8)) { ++ testcase_skip("Token in slot %lu cannot be used with modbits='%lu'", ++ SLOT_ID, tsuite->tv[i].mod_len * 8); ++ free(s); ++ continue; ++ } ++ ++ free(s); ++ ++ // clear buffers ++ memset(decrypt, 0, BIG_REQUEST); ++ ++ // create (private) key handle ++ rc = create_RSAPrivateKey(session, ++ tsuite->tv[i].mod, ++ tsuite->tv[i].pub_exp, ++ tsuite->tv[i].priv_exp, ++ tsuite->tv[i].prime1, ++ tsuite->tv[i].prime2, ++ tsuite->tv[i].exp1, ++ tsuite->tv[i].exp2, ++ tsuite->tv[i].coef, ++ tsuite->tv[i].mod_len, ++ tsuite->tv[i].pubexp_len, ++ tsuite->tv[i].privexp_len, ++ tsuite->tv[i].prime1_len, ++ tsuite->tv[i].prime2_len, ++ tsuite->tv[i].exp1_len, ++ tsuite->tv[i].exp2_len, ++ tsuite->tv[i].coef_len, &priv_key); ++ if (rc != CKR_OK) { ++ if (rc == CKR_POLICY_VIOLATION) { ++ testcase_skip("RSA key import is not allowed by policy"); ++ continue; ++ } ++ ++ testcase_error("create_RSAPrivateKey(), rc=%s", p11_get_ckr(rc)); ++ goto error; ++ } ++ ++ // set cipher buffer length ++ decrypt_len = BIG_REQUEST; ++ ++ // get mech ++ mech = tsuite->mech; ++ ++ // initialize (private key) decryption ++ rc = funcs->C_DecryptInit(session, &mech, priv_key); ++ if (rc != CKR_OK) { ++ testcase_error("C_DecryptInit, rc=%s", p11_get_ckr(rc)); ++ goto tv_cleanup; ++ } ++ // do (private key) decryption ++ rc = funcs->C_Decrypt(session, tsuite->tv[i].msg, tsuite->tv[i].msg_len, ++ decrypt, &decrypt_len); ++ if (rc != CKR_OK) { ++ testcase_error("C_Decrypt, rc=%s", p11_get_ckr(rc)); ++ goto tv_cleanup; ++ } ++ ++ // check results ++ testcase_new_assertion(); ++ ++ if (decrypt_len != tsuite->tv[i].sig_len) { ++ testcase_fail("decrypted length does not match" ++ "expected data length.\n expected length = %lu, " ++ "but found length=%lu.\n", ++ tsuite->tv[i].sig_len, decrypt_len); ++ } else if (memcmp(decrypt, tsuite->tv[i].sig, tsuite->tv[i].sig_len)) { ++ testcase_fail("decrypted data does not match expected data."); ++ } else { ++ testcase_pass("Implicit Rejection."); ++ } ++ ++ // clean up ++tv_cleanup: ++ ++ rc = funcs->C_DestroyObject(session, priv_key); ++ if (rc != CKR_OK) { ++ testcase_error("C_DestroyObject(), rc=%s.", p11_get_ckr(rc)); ++ goto error; ++ } ++ } ++ ++ goto testcase_cleanup; ++error: ++ loc_rc = funcs->C_DestroyObject(session, priv_key); ++ if (loc_rc != CKR_OK) { ++ testcase_error("C_DestroyObject(), rc=%s.", p11_get_ckr(loc_rc)); ++ } ++ ++testcase_cleanup: ++ testcase_user_logout(); ++ loc_rc = funcs->C_CloseAllSessions(slot_id); ++ if (loc_rc != CKR_OK) { ++ testcase_error("C_CloseAllSessions, rc=%s", p11_get_ckr(loc_rc)); ++ } ++ ++ return rc; ++} ++ + CK_RV rsa_funcs(void) + { + unsigned int i; +@@ -2032,6 +2190,13 @@ CK_RV rsa_funcs(void) + break; + } + ++ // Implicit rejection tests ++ for (i = 0; i < NUM_OF_IMPLICIT_REJECTION_TESTSUITES; i++) { ++ rv = do_RSAImplicitRejection(&rsa_implicit_rejection_test_suites[i]); ++ if (rv != CKR_OK && (!no_stop)) ++ break; ++ } ++ + return rv; + } + diff --git a/SOURCES/opencryptoki-CVE-2024-0914-part5.patch b/SOURCES/opencryptoki-CVE-2024-0914-part5.patch new file mode 100644 index 0000000..390eb8a --- /dev/null +++ b/SOURCES/opencryptoki-CVE-2024-0914-part5.patch @@ -0,0 +1,31 @@ +commit d756ba1ec270a289950e66398c7e8be59c4a594d +Author: Ingo Franzki +Date: Fri Feb 9 14:07:34 2024 +0100 + + COMMON: Fix implicit rejection with RSA keys with empty CKA_PRIVATE_EXPONENT + + An RSA key object that has no CKA_PRIVATE_EXPONENT may either don't have that + attribute at all, or may have an empty CKA_PRIVATE_EXPONENT attribute. + Both situations should be handed the same, and the private exponent of the + key needs to be calculated from the other key components. + + Note that RSA key objects generated with a current soft or ICA token will + always have a valid CKA_PRIVATE_EXPONENT attribute, since this is provided + during key generation. + + Signed-off-by: Ingo Franzki + +diff --git a/usr/lib/common/mech_openssl.c b/usr/lib/common/mech_openssl.c +index da515289..14c82e2d 100644 +--- a/usr/lib/common/mech_openssl.c ++++ b/usr/lib/common/mech_openssl.c +@@ -5160,7 +5160,8 @@ CK_RV openssl_specific_rsa_derive_kdk(STDLL_TokData_t *tokdata, OBJECT *key_obj, + + rc = template_attribute_get_non_empty(key_obj->template, + CKA_PRIVATE_EXPONENT, &priv_exp_attr); +- if (rc != CKR_OK && rc != CKR_TEMPLATE_INCOMPLETE) { ++ if (rc != CKR_OK && rc != CKR_TEMPLATE_INCOMPLETE && ++ rc != CKR_ATTRIBUTE_VALUE_INVALID) { + TRACE_ERROR("Failed to get CKA_PRIVATE_EXPONENT\n"); + goto out; + } diff --git a/SPECS/opencryptoki.spec b/SPECS/opencryptoki.spec new file mode 100644 index 0000000..8a996e7 --- /dev/null +++ b/SPECS/opencryptoki.spec @@ -0,0 +1,780 @@ +Name: opencryptoki +Summary: Implementation of the PKCS#11 (Cryptoki) specification v3.0 +Version: 3.22.0 +Release: 3%{?dist} +License: CPL +Group: System Environment/Base +URL: https://github.com/opencryptoki/opencryptoki +Source0: https://github.com/opencryptoki/%{name}/archive/v%{version}/%{name}-%{version}.tar.gz +# bz#1373833, change tmpfiles snippets from /var/lock/* to /run/lock/* +Patch1: opencryptoki-3.11.0-lockdir.patch +# add missing p11sak_defined_attrs.conf +Patch2: opencryptoki-3.21.0-p11sak.patch +# comment some unsupported sandbox options and add /run to ReadWritePaths to exclude +# /run directory from being made read-only on rhel8 +Patch3: opencryptoki-3.21-sandboxing.patch + +# upstream patches +# CVE-2024-0914 opencryptoki: timing side-channel in handling of RSA PKCS#1 v1.5 padded ciphertexts +Patch20: opencryptoki-CVE-2024-0914-part1.patch +Patch21: opencryptoki-CVE-2024-0914-part2.patch +Patch22: opencryptoki-CVE-2024-0914-part3.patch +Patch23: opencryptoki-CVE-2024-0914-part4.patch +Patch24: opencryptoki-CVE-2024-0914-part5.patch + +Requires(pre): coreutils diffutils +Requires: (selinux-policy >= 3.14.3-121 if selinux-policy-targeted) +BuildRequires: gcc +BuildRequires: gcc-c++ +BuildRequires: openssl-devel >= 1.1.1 +BuildRequires: trousers-devel +BuildRequires: openldap-devel +BuildRequires: autoconf automake libtool +BuildRequires: bison flex +BuildRequires: systemd-devel +BuildRequires: libcap-devel +BuildRequires: expect +BuildRequires: make +%ifarch s390 s390x +BuildRequires: libica-devel >= 3.3 +%endif +Requires(pre): %{name}-libs%{?_isa} = %{version}-%{release} +Requires: %{name}-libs%{?_isa} = %{version}-%{release} +Requires: %{name}(token) +Requires(post): systemd +Requires(preun): systemd +Requires(postun): systemd + + +%description +Opencryptoki implements the PKCS#11 specification v2.20 for a set of +cryptographic hardware, such as IBM 4764 and 4765 crypto cards, and the +Trusted Platform Module (TPM) chip. Opencryptoki also brings a software +token implementation that can be used without any cryptographic +hardware. +This package contains the Slot Daemon (pkcsslotd) and general utilities. + + +%package libs +Group: System Environment/Libraries +Summary: The run-time libraries for opencryptoki package +Requires(pre): shadow-utils + +%description libs +Opencryptoki implements the PKCS#11 specification v2.20 for a set of +cryptographic hardware, such as IBM 4764 and 4765 crypto cards, and the +Trusted Platform Module (TPM) chip. Opencryptoki also brings a software +token implementation that can be used without any cryptographic +hardware. +This package contains the PKCS#11 library implementation, and requires +at least one token implementation (packaged separately) to be fully +functional. + + +%package devel +Group: Development/Libraries +Summary: Development files for openCryptoki +Requires: %{name}-libs%{?_isa} = %{version}-%{release} + +%description devel +This package contains the development header files for building +opencryptoki and PKCS#11 based applications + + +%package swtok +Group: System Environment/Libraries +Summary: The software token implementation for opencryptoki +Requires(pre): %{name}-libs%{?_isa} = %{version}-%{release} +Requires: %{name}-libs%{?_isa} = %{version}-%{release} +Provides: %{name}(token) + +%description swtok +Opencryptoki implements the PKCS#11 specification v2.20 for a set of +cryptographic hardware, such as IBM 4764 and 4765 crypto cards, and the +Trusted Platform Module (TPM) chip. Opencryptoki also brings a software +token implementation that can be used without any cryptographic +hardware. +This package brings the software token implementation to use opencryptoki +without any specific cryptographic hardware. + + +%package tpmtok +Group: System Environment/Libraries +Summary: Trusted Platform Module (TPM) device support for opencryptoki +Requires(pre): %{name}-libs%{?_isa} = %{version}-%{release} +Requires: %{name}-libs%{?_isa} = %{version}-%{release} +Provides: %{name}(token) + +%description tpmtok +Opencryptoki implements the PKCS#11 specification v2.20 for a set of +cryptographic hardware, such as IBM 4764 and 4765 crypto cards, and the +Trusted Platform Module (TPM) chip. Opencryptoki also brings a software +token implementation that can be used without any cryptographic +hardware. +This package brings the necessary libraries and files to support +Trusted Platform Module (TPM) devices in the opencryptoki stack. + + +%package icsftok +Group: System Environment/Libraries +Summary: ICSF token support for opencryptoki +Requires(pre): %{name}-libs%{?_isa} = %{version}-%{release} +Requires: %{name}-libs%{?_isa} = %{version}-%{release} +Provides: %{name}(token) + +%description icsftok +Opencryptoki implements the PKCS#11 specification v2.20 for a set of +cryptographic hardware, such as IBM 4764 and 4765 crypto cards, and the +Trusted Platform Module (TPM) chip. Opencryptoki also brings a software +token implementation that can be used without any cryptographic +hardware. +This package brings the necessary libraries and files to support +ICSF token in the opencryptoki stack. + + +%ifarch s390 s390x +%package icatok +Group: System Environment/Libraries +Summary: ICA cryptographic devices (clear-key) support for opencryptoki +Requires(pre): %{name}-libs%{?_isa} = %{version}-%{release} +Requires: %{name}-libs%{?_isa} = %{version}-%{release} +Provides: %{name}(token) + +%description icatok +Opencryptoki implements the PKCS#11 specification v2.20 for a set of +cryptographic hardware, such as IBM 4764 and 4765 crypto cards, and the +Trusted Platform Module (TPM) chip. Opencryptoki also brings a software +token implementation that can be used without any cryptographic +hardware. +This package brings the necessary libraries and files to support ICA +devices in the opencryptoki stack. ICA is an interface to IBM +cryptographic hardware such as IBM 4764 or 4765 that uses the +"accelerator" or "clear-key" path. + +%package ccatok +Group: System Environment/Libraries +Summary: CCA cryptographic devices (secure-key) support for opencryptoki +Requires(pre): %{name}-libs%{?_isa} = %{version}-%{release} +Requires: %{name}-libs%{?_isa} = %{version}-%{release} +Provides: %{name}(token) + +%description ccatok +Opencryptoki implements the PKCS#11 specification v2.20 for a set of +cryptographic hardware, such as IBM 4764 and 4765 crypto cards, and the +Trusted Platform Module (TPM) chip. Opencryptoki also brings a software +token implementation that can be used without any cryptographic +hardware. +This package brings the necessary libraries and files to support CCA +devices in the opencryptoki stack. CCA is an interface to IBM +cryptographic hardware such as IBM 4764 or 4765 that uses the +"co-processor" or "secure-key" path. + +%package ep11tok +Group: System Environment/Libraries +Summary: CCA cryptographic devices (secure-key) support for opencryptoki +Requires(pre): %{name}-libs%{?_isa} = %{version}-%{release} +Requires: %{name}-libs%{?_isa} = %{version}-%{release} +Provides: %{name}(token) + +%description ep11tok +Opencryptoki implements the PKCS#11 specification v2.20 for a set of +cryptographic hardware, such as IBM 4764 and 4765 crypto cards, and the +Trusted Platform Module (TPM) chip. Opencryptoki also brings a software +token implementation that can be used without any cryptographic +hardware. +This package brings the necessary libraries and files to support EP11 +tokens in the opencryptoki stack. The EP11 token is a token that uses +the IBM Crypto Express adapters (starting with Crypto Express 4S adapters) +configured with Enterprise PKCS#11 (EP11) firmware. +%endif + + +%prep +%autosetup -p1 + + +%build +./bootstrap.sh + +%configure --with-systemd=%{_unitdir} \ + --with-pkcsslotd-user=pkcsslotd --with-pkcs-group=pkcs11 \ +%ifarch s390 s390x + --enable-icatok --enable-ccatok --enable-ep11tok --enable-pkcsep11_migrate +%else + --disable-icatok --disable-ccatok --disable-ep11tok --disable-pkcsep11_migrate --disable-pkcscca_migrate +%endif + +make %{?_smp_mflags} CHGRP=/bin/true + + +%install +make install DESTDIR=$RPM_BUILD_ROOT CHGRP=/bin/true + +# Remove unwanted cruft +rm -f $RPM_BUILD_ROOT/%{_libdir}/%{name}/*.la +rm -f $RPM_BUILD_ROOT/%{_libdir}/%{name}/stdll/*.la + + +%post libs -p /sbin/ldconfig +%post swtok -p /sbin/ldconfig +%post tpmtok -p /sbin/ldconfig +%post icsftok -p /sbin/ldconfig +%ifarch s390 s390x +%post icatok -p /sbin/ldconfig +%post ccatok -p /sbin/ldconfig +%post ep11tok -p /sbin/ldconfig +%endif + +%postun libs -p /sbin/ldconfig +%postun swtok -p /sbin/ldconfig +%postun tpmtok -p /sbin/ldconfig +%postun icsftok -p /sbin/ldconfig +%ifarch s390 s390x +%postun icatok -p /sbin/ldconfig +%postun ccatok -p /sbin/ldconfig +%postun ep11tok -p /sbin/ldconfig +%endif + +%pre +# don't touch opencryptoki.conf even if it is unchanged due to new tokversion +# backup config file +%global cfile /etc/opencryptoki/opencryptoki.conf +%global csuffix .rpmsave.XyoP +if test $1 -gt 1 && test -f %{cfile} ; then + cp -p %{cfile} %{cfile}%{csuffix} +fi + +%pre libs +getent group pkcs11 >/dev/null || groupadd -r pkcs11 +getent passwd pkcsslotd >/dev/null || useradd -r -g pkcs11 -d /run/opencryptoki -s /sbin/nologin -c "Opencryptoki pkcsslotd user" pkcsslotd +exit 0 + +%post +# restore the config file from %pre +if test $1 -gt 1 && test -f %{cfile} ; then + if ( ! cmp -s %{cfile} %{cfile}%{csuffix} ) ; then + cp -p %{cfile} %{cfile}.rpmnew + fi + cp -p %{cfile}%{csuffix} %{cfile} && rm -f %{cfile}%{csuffix} +fi + +%systemd_post pkcsslotd.service +if test $1 -eq 1; then + %tmpfiles_create +fi + +%preun +%systemd_preun pkcsslotd.service + +%postun +%systemd_postun_with_restart pkcsslotd.service + +%triggerun -- opencryptoki < 3.21.0-1 +/usr/bin/systemctl daemon-reload + +%files +%doc ChangeLog FAQ README.md +%doc doc/opencryptoki-howto.md +%doc doc/README.token_data +%doc %{_docdir}/%{name}/*.conf +%dir %{_sysconfdir}/%{name} +%verify(not md5 size mtime) %config(noreplace) %{_sysconfdir}/%{name}/%{name}.conf +%attr(0640, root, pkcs11) %config(noreplace) %{_sysconfdir}/%{name}/p11sak_defined_attrs.conf +%attr(0640, root, pkcs11) %config(noreplace) %{_sysconfdir}/%{name}/strength.conf +%{_tmpfilesdir}/%{name}.conf +%{_unitdir}/pkcsslotd.service +%{_sbindir}/p11sak +%{_sbindir}/pkcstok_migrate +%{_sbindir}/pkcsconf +%{_sbindir}/pkcsslotd +%{_sbindir}/pkcsstats +%{_sbindir}/pkcshsm_mk_change +%{_mandir}/man1/p11sak.1* +%{_mandir}/man1/pkcstok_migrate.1* +%{_mandir}/man1/pkcsconf.1* +%{_mandir}/man1/pkcsstats.1* +%{_mandir}/man1/pkcshsm_mk_change.1* +%{_mandir}/man5/policy.conf.5* +%{_mandir}/man5/strength.conf.5* +%{_mandir}/man5/%{name}.conf.5* +%{_mandir}/man5/p11sak_defined_attrs.conf.5* +%{_mandir}/man7/%{name}.7* +%{_mandir}/man8/pkcsslotd.8* +%{_libdir}/opencryptoki/methods +%{_libdir}/pkcs11/methods +%dir %attr(770,root,pkcs11) %{_sharedstatedir}/%{name} +%dir %attr(770,root,pkcs11) %{_sharedstatedir}/%{name}/HSM_MK_CHANGE +%ghost %dir %attr(770,root,pkcs11) %{_rundir}/lock/%{name} +%ghost %dir %attr(770,root,pkcs11) %{_rundir}/lock/%{name}/* +%dir %attr(710,pkcsslotd,pkcs11) /run/%{name} + +%files libs +%license LICENSE +%{_sysconfdir}/ld.so.conf.d/* +# Unversioned .so symlinks usually belong to -devel packages, but opencryptoki +# needs them in the main package, because: +# documentation suggests that programs should dlopen "PKCS11_API.so". +%dir %{_libdir}/opencryptoki +%{_libdir}/opencryptoki/libopencryptoki.* +%{_libdir}/opencryptoki/PKCS11_API.so +%dir %{_libdir}/opencryptoki/stdll +%dir %{_libdir}/pkcs11 +%{_libdir}/pkcs11/libopencryptoki.so +%{_libdir}/pkcs11/PKCS11_API.so +%{_libdir}/pkcs11/stdll +%dir %attr(770,root,pkcs11) %{_localstatedir}/log/opencryptoki + +%files devel +%{_includedir}/%{name}/ +%{_libdir}/pkgconfig/%{name}.pc + +%files swtok +%{_libdir}/opencryptoki/stdll/libpkcs11_sw.* +%{_libdir}/opencryptoki/stdll/PKCS11_SW.so +%dir %attr(770,root,pkcs11) %{_sharedstatedir}/%{name}/swtok/ +%dir %attr(770,root,pkcs11) %{_sharedstatedir}/%{name}/swtok/TOK_OBJ/ + +%files tpmtok +%doc doc/README.tpm_stdll +%{_libdir}/opencryptoki/stdll/libpkcs11_tpm.* +%{_libdir}/opencryptoki/stdll/PKCS11_TPM.so +%dir %attr(770,root,pkcs11) %{_sharedstatedir}/%{name}/tpm/ + +%files icsftok +%doc doc/README.icsf_stdll +%{_sbindir}/pkcsicsf +%{_mandir}/man1/pkcsicsf.1* +%{_libdir}/opencryptoki/stdll/libpkcs11_icsf.* +%{_libdir}/opencryptoki/stdll/PKCS11_ICSF.so +%dir %attr(770,root,pkcs11) %{_sharedstatedir}/%{name}/icsf/ + +%ifarch s390 s390x +%files icatok +%{_libdir}/opencryptoki/stdll/libpkcs11_ica.* +%{_libdir}/opencryptoki/stdll/PKCS11_ICA.so +%dir %attr(770,root,pkcs11) %{_sharedstatedir}/%{name}/lite/ +%dir %attr(770,root,pkcs11) %{_sharedstatedir}/%{name}/lite/TOK_OBJ/ + +%files ccatok +%doc doc/README.cca_stdll +%config(noreplace) %{_sysconfdir}/%{name}/ccatok.conf +%{_sbindir}/pkcscca +%{_mandir}/man1/pkcscca.1* +%{_libdir}/opencryptoki/stdll/libpkcs11_cca.* +%{_libdir}/opencryptoki/stdll/PKCS11_CCA.so +%dir %attr(770,root,pkcs11) %{_sharedstatedir}/%{name}/ccatok/ +%dir %attr(770,root,pkcs11) %{_sharedstatedir}/%{name}/ccatok/TOK_OBJ/ + +%files ep11tok +%doc doc/README.ep11_stdll +%config(noreplace) %{_sysconfdir}/%{name}/ep11tok.conf +%config(noreplace) %{_sysconfdir}/%{name}/ep11cpfilter.conf +%{_sbindir}/pkcsep11_migrate +%{_sbindir}/pkcsep11_session +%{_mandir}/man1/pkcsep11_migrate.1* +%{_mandir}/man1/pkcsep11_session.1* +%{_libdir}/opencryptoki/stdll/libpkcs11_ep11.* +%{_libdir}/opencryptoki/stdll/PKCS11_EP11.so +%dir %attr(770,root,pkcs11) %{_sharedstatedir}/%{name}/ep11tok/ +%dir %attr(770,root,pkcs11) %{_sharedstatedir}/%{name}/ep11tok/TOK_OBJ/ +%endif + + +%changelog +* Fri Feb 16 2024 Than Ngo - 3.22.0-3 +- Fix implicit rejection with RSA keys with empty CKA_PRIVATE_EXPONENT +Related: RHEL-22791 + +* Thu Feb 08 2024 Than Ngo - 3.22.0-2 +- timing side-channel in handling of RSA PKCS#1 v1.5 padded ciphertexts (Marvin) +Resolves: RHEL-22791 + +* Thu Nov 23 2023 Than Ngo - 3.22.0-1 +- Resolves: RHEL-11413, update to 3.22.0 + +* Tue Jul 18 2023 Than Ngo - 3.21.0-9 +- Resolves: #2223588, FTBFS + +* Tue Jul 18 2023 Than Ngo - 3.21.0-8 +- Related: #2222595, add triggerun to reload daemon + +* Fri Jul 14 2023 Than Ngo - 3.21.0-7 +- Resolves: #2222595, p11sak tool: slot option does not accept argument 0 for slot index 0 +- Resolves: #2222594, p11sak fails as soon as there reside non-key objects + +* Tue Jul 04 2023 Than Ngo - 3.21.0-6 +- add workaround for segfault in PEM_write_bio() on OpenSSL 1.1.1 +Related: #2159741 + +* Tue Jun 13 2023 Than Ngo - 3.21.0-5 +- add requirement on selinux-policy >= 3.14.3-121 for pkcsslotd policy sandboxing +Related: #2159697 + +* Thu May 25 2023 Than Ngo - 3.21.0-4 +- add verify attributes for opencryptoki.conf to ignore the verification +Related: #2159697 + +* Mon May 22 2023 Than Ngo - 3.21.0-3 +- pkcsstats: Fix handling of user name +- p11sak: Fix user confirmation prompt behavior when stdin is closed +Related: #2159697 + +* Tue May 16 2023 Than Ngo - 3.21.0-2 +- add missing /var/lib/opencryptoki/HSM_MK_CHANGE +- disable unsupported sandbox options and add /run to ReadWritePaths to exclude + /run directory from being made read-only on rhel8 +Related: #2159697 + +* Mon May 15 2023 Than Ngo - 3.21.0-1 +- Resolves: #1984865, ep11 and cca: support concurrent HSM master key changes +- Resolves: #2110500, ep11 token: PKCS #11 3.0 - support AES_XTS +- Resolves: #2111011, cca token: protected key support +- Resolves: #2159697, update to 3.21.0 +- Resolves: #2159740, pkcsslotd hardening +- Resolves: #2159741, p11sak support Dilithium and Kyber keys +- Resolves: #2159742, ica and soft tokens: PKCS #11 3.0 - support AES_XTS + +* Mon Jan 30 2023 Than Ngo - 3.19.0-2 +- Resolves: #2043856, Support of ep11 token for new IBM Z Hardware (IBM z16) + +* Tue Nov 01 2022 Than Ngo - 3.19.0-1 +- Resolves: #2126612, opencryptoki fails after generating > 500 RSA keys +- Resolves: #2110315, rebase to 3.19.0 +- Resolves: #2110990, openCryptoki key generation with expected MKVP only on CCA and EP11 tokens +- Resolves: #2110477, openCryptoki ep11 token: master key consistency +- Resolves: #1984871, openCryptoki ep11 token: vendor specific key derivation + +* Mon Aug 01 2022 Than Ngo - 3.18.0-3 +- Related: #2043854, do not touch opencryptoki.conf if it is in place already and even if it is unchanged +- Resolves: #2112785, EP11: Fix C_GetMechanismList returning CKR_BUFFER_TOO_SMALL + +* Tue Jun 07 2022 Than Ngo - 3.18.0-2 +- Related: #2043854, fix json output + +* Tue May 24 2022 Than Ngo - 3.18.0-1 +- Resolves: #2043845, rebase to 3.18.0 +- Resolves: #2043854, add crypto counters +- Resolves: #2043855, support crypto profiles + +* Fri Apr 15 2022 Than Ngo - 3.17.0-4 +- Resolves: #2066762, Dilithium support not available + +* Mon Jan 17 2022 Than Ngo - 3.17.0-3 +- Resolves: #2040677, API: Unlock GlobMutex if user and group check fails + +* Tue Nov 09 2021 Than Ngo - 3.17.0-2 +- Related: #1984993, add missing p11sak_defined_attrs.conf + +* Tue Oct 19 2021 Than Ngo - 3.17.0-1 +- Resolves: #1984993, rebase to 3.17.0 +- Resolves: #1984870, openCryptoki key management tool + +* Mon Sep 13 2021 Than Ngo - 3.16.0-6 +- Fix: Could not open /run/lock/opencryptoki/LCK..APIlock + +* Thu Aug 19 2021 Than Ngo - 3.16.0-5 +- Resolves: #1987256, pkcstok_migrate leaves options with multiple strings in opencryptoki.conf options without double-quotes + +* Fri Jul 16 2021 Than Ngo - 3.16.0-4 +- Resolves: #1964304, Fix detection if pkcsslotd is still running + +* Tue Jun 15 2021 Than Ngo - 3.16.0-3 +- Related: #1919223, add conditional requirement + +* Fri Jun 11 2021 Than Ngo - 3.16.0-2 +- Related: #1919223, add requirement on selinux-policy >= 3.14.3-70 for using ipsec + +* Tue Jun 01 2021 Than Ngo - 3.16.0-1 +- Resolves: #1919223, rebase to 3.16.0 +- Resolves: #1922195, Event Notification Support +- Resolves: #1959936, Soft token does not check if an EC key is valid +- Resolves: #1851104, import and export of secure key objects +- Resolves: #1851106, openCryptoki ep11 token: protected key support +- Resolves: #1851107, openCryptoki ep11 token: support attribute bound keys + +* Fri Feb 12 2021 Than Ngo - 3.15.1-5 +- Resolves: #1928120, Fix problem with C_Get/SetOperationState and digest contexts + +* Fri Feb 12 2021 Than Ngo - 3.15.1-4 +- Resolves: #1927745, pkcscca migration fails with usr/sb2 is not a valid slot ID + +* Thu Nov 26 2020 Than Ngo - 3.15.1-3 +- Resolves: #1902022 + Fix compiling with c++ + Added error message handling for p11sak remove-key command + +* Thu Nov 26 2020 Than Ngo - 3.15.1-2 +- Related: #1847433, Added error message handling for p11sak remove-key command + +* Mon Nov 02 2020 Than Ngo - 3.15.1-1 +- Related: #1847433 + upstream fixes: + - Free generated key in all error cases + - CCA: Zeroize key buffer to avoid CCA 8/32 error + - Do not delete the map-btree entry if destroying an object is not allowed + - Remove now unused header timeb.h + - TESTCASES: Use FIPS conforming keys for 3DES CBC-MAC test vectors + - Fix buffer overrun in C_CopyObject + - TPM: Fix double free in openssl_gen_key + +* Mon Oct 19 2020 Than Ngo - 3.15.0-1 +- Resolves: #1847433, rebase to 3.15.0 +- Resolves: #1851105, PKCS #11 3.0 - baseline provider support +- Resolves: #1851108, openCryptoki ep11 token: enhanced functionality +- Resolves: #1851109, openCryptoki key management tool: key deletion function + +* Mon Jul 06 2020 Than Ngo - 3.14.0-5 +- Related: #1853420, more fixes + +* Fri Jul 03 2020 Than Ngo - 3.14.0-4 +- Resolves: #1853420, endian issue + +* Mon Jun 15 2020 Than Ngo - 3.14.0-3 +- Resolves: #1780294, PIN conversion tool + +* Tue May 26 2020 Than Ngo - 3.14.0-2 +- Related: #1780293, fix regression, segfault in C_SetPin + +* Tue May 19 2020 Than Ngo - 3.14.0-1 +- Resolves: #1723863 - ep11 token: Enhanced Support +- Resolves: #1780285 - ep11 token: Support for new IBM Z hardware z15 +- Resolves: #1780293 - rebase to 3.14.0 +- Resolves: #1800549 - key management tool: list keys function + -Resolves: #1800555 - key management tool: random key generation function + +* Fri Dec 13 2019 Than Ngo - 3.12.1-2 +- Resolves: #1782445, EP11: Fix EC-uncompress buffer length + +* Thu Nov 28 2019 Than Ngo - 3.12.1-1 +- Resolves: #1777313, rebase to 3.12.1 + +* Tue Nov 12 2019 Than Ngo - 3.12.0-1 +- Resolves: #1726243, rebase to 3.12.0 + +* Mon Aug 26 2019 Dan Horák - 3.11.1-2 +- Resolves: #1739433, ICA HW token missing after the package update + +* Mon May 06 2019 Than Ngo - 3.11.1-1 +- Resolves: #1706140, rebase to 3.11.1 + +* Tue Mar 26 2019 Than Ngo - 3.11.0-3 +- Resolves: #1667941, 3des tests failures due to FIPS incompatible test scenarios +- Resolves: #1651731, ep11 token: enhanced IBM z14 functions +- Resolves: #1651732, ep11 token: support m_*Single functions from ep11 lib +- Resolves: #1525407, use CPACF hashes in ep11 token +- Resolves: #1651238, rebase to 3.11.0 +- Resolves: #1682530, gating + +* Fri Dec 14 2018 Than Ngo - 3.10.0-3 +- Resolves: #1657683, can't establish libica token in FIPS mode +- Resolves: #1652856, EP11 token fails when using Strict-Session mode or VHSM-Mode + +* Thu Oct 25 2018 Than Ngo - 3.10.0-2 +- Resolves: #1602641, covscan + +* Tue Jun 12 2018 Dan Horák - 3.10.0-1 +- Rebase to 3.10.0 + +* Fri Feb 23 2018 Dan Horák - 3.9.0-1 +- Rebase to 3.9.0 + +* Thu Feb 08 2018 Fedora Release Engineering - 3.8.2-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild + +* Fri Nov 24 2017 Dan Horák - 3.8.2-2 +- use upstream tmpfiles config + +* Thu Nov 23 2017 Dan Horák - 3.8.2-1 +- Rebase to 3.8.2 (#1512678) + +* Thu Aug 03 2017 Fedora Release Engineering - 3.7.0-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild + +* Thu Jul 27 2017 Fedora Release Engineering - 3.7.0-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild + +* Wed May 17 2017 Sinny Kumari - 3.7.0-1 +- Rebase to 3.7.0 +- Added libitm-devel as BuildRequires + +* Mon Apr 03 2017 Sinny Kumari - 3.6.2-1 +- Rebase to 3.6.2 +- RHBZ#1424017 - opencryptoki: FTBFS in rawhide + +* Sat Feb 11 2017 Fedora Release Engineering - 3.5.1-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild + +* Thu Sep 01 2016 Jakub Jelen - 3.5.1-1 +- New upstream release + +* Tue May 03 2016 Jakub Jelen - 3.5-1 +- New upstream release + +* Thu Feb 04 2016 Fedora Release Engineering - 3.4.1-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild + +* Mon Dec 07 2015 Jakub Jelen 3.4.1-1 +- New bugfix upstream release + +* Wed Nov 18 2015 Jakub Jelen 3.4-1 +- New upstream release +- Adding post-release patch fixing compile warnings + +* Thu Aug 27 2015 Jakub Jelen 3.3-1.1 +- New upstream release +- Correct dependencies for group creation + +* Wed Jun 17 2015 Fedora Release Engineering - 3.2-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild + +* Thu May 07 2015 Jakub Jelen 3.2-3 +- Few more undefined symbols fixed for s390(x) specific targets +- Do not require --no-undefined, because s390(x) requires some + +* Mon May 04 2015 Jakub Jelen 3.2-2 +- Fix missing sources and libraries in makefiles causing undefined symbols (#1193560) +- Make inline function compatible for GCC5 + +* Wed Sep 10 2014 Petr Lautrbach 3.2-1 +- new upstream release 3.2 +- add new sub-package opencryptoki-ep11tok on s390x + +* Sun Aug 17 2014 Fedora Release Engineering - 3.1-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild + +* Thu Jul 24 2014 Petr Lautrbach 3.1-1 +- new upstream release 3.1 + +* Sat Jun 07 2014 Fedora Release Engineering - 3.0-11 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild + +* Mon Feb 17 2014 Petr Lautrbach 3.0-10 +- create the right lock directory for cca tokens (#1054442) + +* Wed Jan 29 2014 Petr Lautrbach 3.0-9 +- use Requires(pre): opencryptoki-libs for subpackages + +* Mon Jan 20 2014 Dan Horák - 3.0-8 +- include token specific directories (#1013017, #1045775, #1054442) +- fix pkcsconf crash for non-root users (#10054661) +- the libs subpackage must care of creating the pkcs11 group, it's the first to be installed + +* Tue Dec 03 2013 Dan Horák - 3.0-7 +- fix build with -Werror=format-security (#1037228) + +* Fri Nov 22 2013 Dan Horák - 3.0-6 +- apply post-3.0 fixes (#1033284) + +* Tue Nov 19 2013 Dan Horák - 3.0-5 +- update opencryptoki man page (#1001729) + +* Fri Aug 23 2013 Dan Horák - 3.0-4 +- update unit file (#995002) + +* Sat Aug 03 2013 Fedora Release Engineering - 3.0-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild + +* Tue Jul 23 2013 Dan Horák - 3.0-2 +- update pkcsconf man page (#948460) + +* Mon Jul 22 2013 Dan Horák - 3.0-1 +- new upstream release 3.0 + +* Tue Jun 25 2013 Dan Horák - 2.4.3.1-1 +- new upstream release 2.4.3.1 + +* Fri May 03 2013 Dan Horák - 2.4.3-1 +- new upstream release 2.4.3 + +* Thu Apr 04 2013 Dan Horák - 2.4.2-4 +- enable hardened build +- switch to systemd macros in scriptlets (#850240) + +* Mon Jan 28 2013 Dan Horák - 2.4.2-3 +- add virtual opencryptoki(token) Provides to token modules and as Requires + to main package (#904986) + +* Fri Jul 20 2012 Fedora Release Engineering - 2.4.2-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Thu Jun 21 2012 Dan Horák - 2.4.2-1 +- new upstream release 2.4.2 +- add pkcs_slot man page +- don't add root to the pkcs11 group + +* Mon Jun 11 2012 Dan Horák - 2.4.1-2 +- fix unresolved symbols in TPM module (#830129) + +* Sat Feb 25 2012 Dan Horák - 2.4.1-1 +- new upstream release 2.4.1 +- convert from initscript to systemd unit +- import fixes from RHEL-6 about root's group membership (#732756, #730903) + +* Fri Jan 13 2012 Fedora Release Engineering - 2.4-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild + +* Thu Jul 07 2011 Dan Horák - 2.4-1 +- new upstream release 2.4 + +* Tue Feb 08 2011 Fedora Release Engineering - 2.3.3-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + +* Mon Jan 17 2011 Dan Horák 2.3.3-1 +- new upstream release 2.3.3 + +* Tue Nov 09 2010 Michal Schmidt 2.3.2-2 +- Apply Obsoletes to package names, not provides. + +* Tue Sep 14 2010 Dan Horák 2.3.2-1 +- new upstream release 2.3.2 +- put STDLLs in separate packages to match upstream package design + +* Thu Jul 08 2010 Michal Schmidt 2.3.1-7 +- Move the LICENSE file to the -libs subpackage. + +* Tue Jun 29 2010 Dan Horák 2.3.1-6 +- rebuilt with CCA enabled (#604287) +- fixed issues from #546274 + +* Fri Apr 30 2010 Dan Horák 2.3.1-5 +- fixed one more issue in the initscript (#547324) + +* Mon Apr 26 2010 Dan Horák 2.3.1-4 +- fixed pidfile creating and usage (#547324) + +* Mon Feb 08 2010 Michal Schmidt 2.3.1-3 +- Also list 'reload' and 'force-reload' in "Usage: ...". + +* Mon Feb 08 2010 Michal Schmidt 2.3.1-2 +- Support 'force-reload' in the initscript. + +* Wed Jan 27 2010 Michal Schmidt 2.3.1-1 +- New upstream release 2.3.1. +- opencryptoki-2.3.0-fix-nss-breakage.patch was merged. + +* Fri Jan 22 2010 Dan Horák 2.3.0-5 +- made pkcsslotd initscript LSB compliant (#522149) + +* Mon Sep 07 2009 Michal Schmidt 2.3.0-4 +- Added opencryptoki-2.3.0-fix-nss-breakage.patch on upstream request. + +* Fri Aug 21 2009 Tomas Mraz - 2.3.0-3 +- rebuilt with new openssl + +* Sun Aug 16 2009 Michal Schmidt 2.3.0-2 +- Require libica-2.0. + +* Fri Aug 07 2009 Michal Schmidt 2.3.0-1 +- New upstream release 2.3.0: + - adds support for RSA 4096 bit keys in the ICA token. + +* Tue Jul 21 2009 Michal Schmidt - 2.2.8-5 +- Require arch-specific dependency on -libs. + +* Tue Jul 21 2009 Michal Schmidt - 2.2.8-4 +- Return support for crypto hw on s390. +- Renamed to opencryptoki. +- Simplified multilib by putting libs in subpackage as suggested by Dan Horák. + +* Tue Jul 21 2009 Michal Schmidt - 2.2.8-2 +- Fedora package based on RHEL-5 package.