From f1774cb8956a35269f539efcee99fe7eda838b77 Mon Sep 17 00:00:00 2001 From: Vitaly Chikunov Date: Thu, 11 Apr 2019 18:51:17 +0300 Subject: X.509: parse public key parameters from x509 for akcipher Some public key algorithms (like EC-DSA) keep in parameters field important data such as digest and curve OIDs (possibly more for different EC-DSA variants). Thus, just setting a public key (as for RSA) is not enough. Append parameters into the key stream for akcipher_set_{pub,priv}_key. Appended data is: (u32) algo OID, (u32) parameters length, parameters data. This does not affect current akcipher API nor RSA ciphers (they could ignore it). Idea of appending parameters to the key stream is by Herbert Xu. Cc: David Howells Cc: Denis Kenzior Cc: keyrings@vger.kernel.org Signed-off-by: Vitaly Chikunov Reviewed-by: Denis Kenzior Signed-off-by: Herbert Xu --- crypto/testmgr.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) (limited to 'crypto/testmgr.c') diff --git a/crypto/testmgr.c b/crypto/testmgr.c index 21b27996508a..bc382b0c0ac6 100644 --- a/crypto/testmgr.c +++ b/crypto/testmgr.c @@ -2585,6 +2585,12 @@ static int alg_test_kpp(const struct alg_test_desc *desc, const char *driver, return err; } +static u8 *test_pack_u32(u8 *dst, u32 val) +{ + memcpy(dst, &val, sizeof(val)); + return dst + sizeof(val); +} + static int test_akcipher_one(struct crypto_akcipher *tfm, const struct akcipher_testvec *vecs) { @@ -2599,6 +2605,7 @@ static int test_akcipher_one(struct crypto_akcipher *tfm, const char *m, *c; unsigned int m_size, c_size; const char *op; + u8 *key, *ptr; if (testmgr_alloc_buf(xbuf)) return err; @@ -2609,12 +2616,20 @@ static int test_akcipher_one(struct crypto_akcipher *tfm, crypto_init_wait(&wait); + key = kmalloc(vecs->key_len + sizeof(u32) * 2 + vecs->param_len, + GFP_KERNEL); + if (!key) + goto free_xbuf; + memcpy(key, vecs->key, vecs->key_len); + ptr = key + vecs->key_len; + ptr = test_pack_u32(ptr, vecs->algo); + ptr = test_pack_u32(ptr, vecs->param_len); + memcpy(ptr, vecs->params, vecs->param_len); + if (vecs->public_key_vec) - err = crypto_akcipher_set_pub_key(tfm, vecs->key, - vecs->key_len); + err = crypto_akcipher_set_pub_key(tfm, key, vecs->key_len); else - err = crypto_akcipher_set_priv_key(tfm, vecs->key, - vecs->key_len); + err = crypto_akcipher_set_priv_key(tfm, key, vecs->key_len); if (err) goto free_req; @@ -2744,6 +2759,7 @@ free_all: kfree(outbuf_enc); free_req: akcipher_request_free(req); + kfree(key); free_xbuf: testmgr_free_buf(xbuf); return err; -- cgit v1.2.3