From 9b25b05d7aa4a816cfa06f4750cb600cb94e27b7 Mon Sep 17 00:00:00 2001 From: Stef Walter Date: Wed, 18 Nov 2009 17:30:31 +0000 Subject: Add support for checking AES keys and DH derive --- src/dh.c | 131 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) (limited to 'src/dh.c') diff --git a/src/dh.c b/src/dh.c index 3325caa..7016498 100644 --- a/src/dh.c +++ b/src/dh.c @@ -7,6 +7,137 @@ #include +static int +compare_secret_values (void *one, size_t n_one, void *two, size_t n_two) +{ + if (n_one > n_two) + return memcmp (one + (n_one - n_two), two, n_two); + else + return memcmp (one, two + (n_two - n_one), n_one); +} + +static DH* +generate_peer_dh (CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key) +{ + CK_ATTRIBUTE attrs[2]; + CK_BYTE prime[16384]; + CK_BYTE base[1024]; + DH *dh; + + attrs[0].type = CKA_PRIME; + attrs[0].ulValueLen = sizeof (prime); + attrs[0].pValue = prime; + + attrs[1].type = CKA_BASE; + attrs[1].ulValueLen = sizeof (base); + attrs[1].pValue = base; + + if (!p11t_object_get (session, key, attrs, 2)) + return NULL; + + if(attrs[0].ulValueLen == CK_INVALID || + attrs[1].ulValueLen == CK_INVALID) + return NULL; + + dh = DH_new (); + dh->p = BN_bin2bn (prime, attrs[0].ulValueLen, NULL); + dh->g = BN_bin2bn (base, attrs[1].ulValueLen, NULL); + assert(dh && dh->p && dh->g); + + if (!DH_generate_key (dh)) { + DH_free (dh); + return NULL; + } + + return dh; +} + +int +test_dh_private_derive (CK_SESSION_HANDLE session, CK_OBJECT_HANDLE pub, CK_OBJECT_HANDLE prv) +{ + CK_ATTRIBUTE attrs[3]; + CK_KEY_TYPE key_type = CKK_AES; + CK_OBJECT_CLASS klass = CKO_SECRET_KEY; + CK_BYTE buffer[16384]; + CK_BYTE value[16384]; + CK_OBJECT_HANDLE derived; + CK_MECHANISM mech; + BIGNUM *our_pub; + CK_RV rv; + DH *dh; + + P11T_SECTION("C_DeriveKey"); + + /* Setup peer's DH */ + dh = generate_peer_dh (session, pub); + if (dh == NULL) + p11t_check_warn ("Couldn't retrieve DH parameters from DH pub key"); + + /* Dig out our public key */ + attrs[0].type = CKA_VALUE; + attrs[0].pValue = value; + attrs[0].ulValueLen = sizeof (value); + if (p11t_object_get (session, pub, attrs, 1)) { + our_pub = BN_bin2bn (value, attrs[0].ulValueLen, NULL); + } else { + p11t_check_warn ("Couldn't retrieve DH public value from DH pub key"); + our_pub = NULL; + } + + mech.mechanism = CKM_DH_PKCS_DERIVE; + mech.pParameter = buffer; + mech.ulParameterLen = BN_num_bytes (dh->pub_key); + BN_bn2bin (dh->pub_key, buffer); + + /* TODO: How can we know this key type is supported? */ + attrs[0].type = CKA_KEY_TYPE; + attrs[0].pValue = &key_type; + attrs[0].ulValueLen = sizeof (key_type); + + attrs[1].type = CKA_CLASS; + attrs[1].pValue = &klass; + attrs[1].ulValueLen = sizeof (klass); + + rv = (p11t_module_funcs->C_DeriveKey) (session, &mech, prv, attrs, 2, &derived); + P11T_CHECK_RV ("CKM_DH_PKCS_DERIVE", rv, CKR_OK); + + /* Compare to our generated key */ + attrs[0].type = CKA_VALUE; + attrs[0].pValue = value; + attrs[0].ulValueLen = sizeof (value); + if (p11t_object_get (session, derived, attrs, 1) && attrs[0].ulValueLen != (CK_ULONG)-1 && + dh != NULL && our_pub != NULL) { + if (!DH_compute_key (buffer, our_pub, dh)) + assert (0); + if (compare_secret_values (value, attrs[0].ulValueLen, buffer, DH_size (dh)) != 0) + P11T_CHECK_FAIL_MSG ("CKM_DH_PKCS_DERIVE", "Derived key has wrong secret value"); + } + + BN_free (our_pub); + DH_free (dh); + + return p11t_key_test (session, derived, CKO_SECRET_KEY); +} + +int +p11t_dh_test_key_pair (CK_SESSION_HANDLE session, CK_OBJECT_HANDLE pub, CK_OBJECT_HANDLE prv) +{ + CK_ULONG mechanisms[128]; + CK_ATTRIBUTE attr = { CKA_ALLOWED_MECHANISMS, mechanisms, sizeof (mechanisms) }; + CK_ULONG i; + + /* Let's see if it support derivation */ + if (!p11t_object_get (session, prv, &attr, 1)) + return STOP; + + for (i = 0; i < attr.ulValueLen / sizeof (CK_ULONG); ++i) { + if (mechanisms[i] == CKM_DH_PKCS_DERIVE) + test_dh_private_derive (session, pub, prv); + } + + return CONTINUE; +} + static void test_dh_key_pair_gen (CK_SLOT_ID slot, CK_MECHANISM_TYPE mech, CK_MECHANISM_INFO_PTR info) { -- cgit v1.2.3