Libica might hang if we provide an even public exponent for RSA keypair generation.
Convert to a local representation (long int) so we can check. Also use p11_bignum_trim() to (possibly) trim-down the field sizes for the generated key. Signed-off-by: Klaus Heinrich Kiwi <[email protected]> --- usr/lib/pkcs11/ica_s390_stdll/ica_specific.c | 91 +++++++++++++++++++++----- 1 files changed, 74 insertions(+), 17 deletions(-) diff --git a/usr/lib/pkcs11/ica_s390_stdll/ica_specific.c b/usr/lib/pkcs11/ica_s390_stdll/ica_specific.c index 03c2545..92987e1 100755 --- a/usr/lib/pkcs11/ica_s390_stdll/ica_specific.c +++ b/usr/lib/pkcs11/ica_s390_stdll/ica_specific.c @@ -303,6 +303,7 @@ #endif #include "pkcs11types.h" +#include "p11util.h" #include "defs.h" #include "host_defs.h" #include "h_extern.h" @@ -1713,7 +1714,6 @@ rsa_convert_crt_key( CK_ATTRIBUTE * modulus, } - // CK_RV os_specific_rsa_keygen(TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl) @@ -1723,6 +1723,7 @@ os_specific_rsa_keygen(TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl) CK_BYTE * ptr = NULL; CK_ULONG mod_bits; CK_BBOOL flag; + unsigned long tmpsize; CK_RV rc; ica_rsa_key_mod_expo_t * publKey = NULL; ica_rsa_key_crt_t * privKey = NULL; @@ -1785,9 +1786,24 @@ os_specific_rsa_keygen(TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl) /* Use the provided public exponent: * all fields must be right-aligned, so make * sure we only use the rightmost part */ + /* We know the pub_exp attribute has it's value in BIG ENDIAN * + * byte order, and we're assuming we're on s390(x) which is also * + * BIG ENDIAN, so no byte swapping required. * + * FIXME: Will need to fix that if porting for little endian */ ptr = publKey->exponent + publKey->key_length - publ_exp->ulValueLen; memcpy(ptr, publ_exp->pValue, publ_exp->ulValueLen); + /* If the public exponent is zero, libica will generate a random one * + * If it is an even number, then we have a problem. Use ptr to cast * + * to unsigned int and check */ + ptr = publKey->exponent + publKey->key_length - sizeof (unsigned long); + if ( *( (unsigned long *)ptr) != 0 && + *( (unsigned long *)ptr) % 2 == 0 ) { + st_err_log(20, __FILE__, __LINE__); + return CKR_TEMPLATE_INCONSISTENT; + } + + /* Build privKey: * buffers pointed by p, q, dp, dq and qInverse in struct * ica_rsa_key_crt_t must be of size key_legth/2 or larger. @@ -1850,17 +1866,38 @@ os_specific_rsa_keygen(TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl) } + /* Build the PKCS#11 public key */ // modulus: n // - rc = build_attribute( CKA_MODULUS, publKey->modulus, - publKey->key_length, &attr ); + tmpsize = publKey->key_length; + ptr = p11_bigint_trim(publKey->modulus, &tmpsize); + if (tmpsize != publKey->key_length) { + /* This is bad */ + st_err_log(4, __FILE__, __LINE__, __FUNCTION__); + rc = CKR_FUNCTION_FAILED; + goto privkey_cleanup; + } + rc = build_attribute( CKA_MODULUS, ptr, + tmpsize, &attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto privkey_cleanup; } template_update_attribute( publ_tmpl, attr ); - + // public exponent + // + tmpsize = publKey->key_length; + ptr = p11_bigint_trim(publKey->exponent, &tmpsize); + rc = build_attribute( CKA_PUBLIC_EXPONENT, ptr, + tmpsize, &attr); + if (rc != CKR_OK){ + st_err_log(84, __FILE__, __LINE__); + goto privkey_cleanup; + } + template_update_attribute( publ_tmpl, attr ); + + // local = TRUE // flag = TRUE; @@ -1877,7 +1914,9 @@ os_specific_rsa_keygen(TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl) // public exponent: e // - rc = build_attribute( CKA_PUBLIC_EXPONENT, publ_exp->pValue, publ_exp->ulValueLen, &attr ); + tmpsize = publKey->key_length; + ptr = p11_bigint_trim(publKey->exponent, &tmpsize); + rc = build_attribute( CKA_PUBLIC_EXPONENT, ptr, tmpsize, &attr ); if (rc != CKR_OK) { st_err_log(84, __FILE__, __LINE__); goto privkey_cleanup; @@ -1886,18 +1925,28 @@ os_specific_rsa_keygen(TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl) // modulus: n // - rc = build_attribute( CKA_MODULUS, publKey->modulus, - publKey->key_length, &attr ); + tmpsize = publKey->key_length; + ptr = p11_bigint_trim(publKey->modulus, &tmpsize); + if (tmpsize != publKey->key_length) { + /* This is bad */ + st_err_log(4, __FILE__, __LINE__, __FUNCTION__); + rc = CKR_FUNCTION_FAILED; + goto privkey_cleanup; + } + rc = build_attribute( CKA_MODULUS, ptr, + tmpsize, &attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); - return rc; + goto privkey_cleanup; } template_update_attribute( priv_tmpl, attr ); // exponent 1: d mod(p-1) // - rc = build_attribute( CKA_EXPONENT_1, privKey->dp + 8, - privKey->key_length/2, &attr ); + tmpsize = privKey->key_length/2; + ptr = p11_bigint_trim(privKey->dp + 8, &tmpsize); + rc = build_attribute( CKA_EXPONENT_1, ptr, + tmpsize, &attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto privkey_cleanup; @@ -1906,8 +1955,10 @@ os_specific_rsa_keygen(TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl) // exponent 2: d mod(q-1) // - rc = build_attribute( CKA_EXPONENT_2, privKey->dq, - privKey->key_length/2, &attr ); + tmpsize = privKey->key_length/2; + ptr = p11_bigint_trim(privKey->dq, &tmpsize); + rc = build_attribute( CKA_EXPONENT_2, ptr, + tmpsize, &attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto privkey_cleanup; @@ -1916,17 +1967,21 @@ os_specific_rsa_keygen(TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl) // prime #1: p // - rc = build_attribute( CKA_PRIME_1, privKey->p + 8, - privKey->key_length/2, &attr ); + tmpsize = privKey->key_length/2; + ptr = p11_bigint_trim(privKey->p + 8, &tmpsize); + rc = build_attribute( CKA_PRIME_1, ptr, + tmpsize, &attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto privkey_cleanup; } template_update_attribute( priv_tmpl, attr ); - + // prime #2: q // + tmpsize = privKey->key_length/2; + ptr = p11_bigint_trim(privKey->q, &tmpsize); rc = build_attribute( CKA_PRIME_2, privKey->q, privKey->key_length/2, &attr ); if (rc != CKR_OK){ @@ -1938,8 +1993,10 @@ os_specific_rsa_keygen(TEMPLATE *publ_tmpl, TEMPLATE *priv_tmpl) // CRT coefficient: q_inverse mod(p) // - rc = build_attribute( CKA_COEFFICIENT, privKey->qInverse + 8, - privKey->key_length/2, &attr ); + tmpsize = privKey->key_length/2; + ptr = p11_bigint_trim(privKey->qInverse + 8, &tmpsize); + rc = build_attribute( CKA_COEFFICIENT, ptr, + tmpsize, &attr ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto privkey_cleanup; -- 1.7.2.3 ------------------------------------------------------------------------------ Increase Visibility of Your 3D Game App & Earn a Chance To Win $500! Tap into the largest installed PC base & get more eyes on your game by optimizing for Intel(R) Graphics Technology. Get started today with the Intel(R) Software Partner Program. Five $500 cash prizes are up for grabs. http://p.sf.net/sfu/intelisp-dev2dev _______________________________________________ Opencryptoki-tech mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/opencryptoki-tech
