* [RFC PATCH v2 0/4] crypto: (ec)dh - add privkey generation support
@ 2017-05-17 15:26 Tudor Ambarus
2017-05-17 15:26 ` [RFC PATCH v2 1/4] crypto: ecc " Tudor Ambarus
` (3 more replies)
0 siblings, 4 replies; 14+ messages in thread
From: Tudor Ambarus @ 2017-05-17 15:26 UTC (permalink / raw)
To: herbert, davem
Cc: linux-crypto, smueller, marcel, Nicolas.Ferre, Tudor Ambarus
Hi,
This is an RFC to discuss how to support private key generation for dh and ecdh.
This is helpful in a user-space to kernel (ec)dh offload because the keys are
generated in kernel and never revealed to user-space.
Private key generation is also helpful to implement forward secrecy.
A public/private key system demonstrates the property of forward secrecy if it
creates new key pairs for each communication session. These key pairs are
generated on an as-needed basis and are destroyed after the session is over.
If an attacker were to record previous encrypted session data, they wouldn't be
able to decrypt it with possession of a long-term key.
There are crypto accelerators that are capable of generating and retaining
private keys without revealing them to software. This patch set is a
prerequisite for hardware private key generation support.
Changes in v2:
- free dh params in case of error
- code defensively in testmgr: use sizeof(*ptr) while in memcpy
v1 can be found at:
http://www.mail-archive.com/linux-crypto@vger.kernel.org/msg25176.html
Tudor Ambarus (4):
crypto: ecc - add privkey generation support
crypto: ecdh - allow user to provide NULL privkey
crypto: dh - allow user to provide NULL privkey
crypto: testmgr - add genkey kpp test
crypto/dh.c | 21 ++++++++
crypto/ecc.c | 20 +++++++
crypto/ecc.h | 14 +++++
crypto/ecdh.c | 4 ++
crypto/testmgr.c | 76 +++++++++++++++++++++++----
crypto/testmgr.h | 155 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
6 files changed, 279 insertions(+), 11 deletions(-)
--
2.7.4
^ permalink raw reply [flat|nested] 14+ messages in thread* [RFC PATCH v2 1/4] crypto: ecc - add privkey generation support 2017-05-17 15:26 [RFC PATCH v2 0/4] crypto: (ec)dh - add privkey generation support Tudor Ambarus @ 2017-05-17 15:26 ` Tudor Ambarus 2017-05-28 18:44 ` Stephan Müller 2017-05-17 15:26 ` [RFC PATCH v2 2/4] crypto: ecdh - allow user to provide NULL privkey Tudor Ambarus ` (2 subsequent siblings) 3 siblings, 1 reply; 14+ messages in thread From: Tudor Ambarus @ 2017-05-17 15:26 UTC (permalink / raw) To: herbert, davem Cc: linux-crypto, smueller, marcel, Nicolas.Ferre, Tudor Ambarus Add support for generating ecc private keys. Generation of ecc private keys is helpful in a user-space to kernel ecdh offload because the keys are not revealed to user-space. Private key generation is also helpful to implement forward secrecy. Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com> --- crypto/ecc.c | 20 ++++++++++++++++++++ crypto/ecc.h | 14 ++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/crypto/ecc.c b/crypto/ecc.c index 414c78a..a591907 100644 --- a/crypto/ecc.c +++ b/crypto/ecc.c @@ -927,6 +927,26 @@ int ecc_is_key_valid(unsigned int curve_id, unsigned int ndigits, return 0; } +int ecc_gen_privkey(unsigned int curve_id, unsigned int ndigits, u64 *privkey) +{ + const struct ecc_curve *curve = ecc_get_curve(curve_id); + u64 priv[ndigits]; + unsigned int nbytes = ndigits << ECC_DIGITS_TO_BYTES_SHIFT; + + get_random_bytes(priv, nbytes); + + if (vli_is_zero(priv, ndigits)) + return -EINVAL; + + /* Make sure the private key is in the range [1, n-1]. */ + if (vli_cmp(curve->n, priv, ndigits) != 1) + return -EINVAL; + + ecc_swap_digits(priv, privkey, ndigits); + + return 0; +} + int ecdh_make_pub_key(unsigned int curve_id, unsigned int ndigits, const u8 *private_key, unsigned int private_key_len, u8 *public_key, unsigned int public_key_len) diff --git a/crypto/ecc.h b/crypto/ecc.h index 663d598..b94b7ce 100644 --- a/crypto/ecc.h +++ b/crypto/ecc.h @@ -44,6 +44,20 @@ int ecc_is_key_valid(unsigned int curve_id, unsigned int ndigits, const u8 *private_key, unsigned int private_key_len); /** + * ecc_gen_privkey() - Generates an ECC private key. + * The private key is a random integer in the range 0 < random < n, where n is a + * prime that is the order of the cyclic subgroup generated by the distinguished + * point G. + * @curve_id: id representing the curve to use + * @ndigits: curve number of digits + * @private_key: buffer for storing the generated private key + * + * Returns 0 if the private key was generated successfully, a negative value + * if an error occurred. + */ +int ecc_gen_privkey(unsigned int curve_id, unsigned int ndigits, u64 *privkey); + +/** * ecdh_make_pub_key() - Compute an ECC public key * * @curve_id: id representing the curve to use -- 2.7.4 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [RFC PATCH v2 1/4] crypto: ecc - add privkey generation support 2017-05-17 15:26 ` [RFC PATCH v2 1/4] crypto: ecc " Tudor Ambarus @ 2017-05-28 18:44 ` Stephan Müller 2017-05-29 9:08 ` Tudor Ambarus 0 siblings, 1 reply; 14+ messages in thread From: Stephan Müller @ 2017-05-28 18:44 UTC (permalink / raw) To: Tudor Ambarus; +Cc: herbert, davem, linux-crypto, marcel, Nicolas.Ferre Am Mittwoch, 17. Mai 2017, 17:26:50 CEST schrieb Tudor Ambarus: Hi Tudor, > Add support for generating ecc private keys. > > Generation of ecc private keys is helpful in a user-space to kernel > ecdh offload because the keys are not revealed to user-space. Private > key generation is also helpful to implement forward secrecy. > > Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com> > --- > crypto/ecc.c | 20 ++++++++++++++++++++ > crypto/ecc.h | 14 ++++++++++++++ > 2 files changed, 34 insertions(+) > > diff --git a/crypto/ecc.c b/crypto/ecc.c > index 414c78a..a591907 100644 > --- a/crypto/ecc.c > +++ b/crypto/ecc.c > @@ -927,6 +927,26 @@ int ecc_is_key_valid(unsigned int curve_id, unsigned > int ndigits, return 0; > } > > +int ecc_gen_privkey(unsigned int curve_id, unsigned int ndigits, u64 > *privkey) +{ > + const struct ecc_curve *curve = ecc_get_curve(curve_id); Shouldn't there be a check that a curve is selected? I.e. a check for an error should be added? > + u64 priv[ndigits]; Shouldn't there be a size check of ndigits? > + unsigned int nbytes = ndigits << ECC_DIGITS_TO_BYTES_SHIFT; > + > + get_random_bytes(priv, nbytes); Can you please use crypto_get_default_rng / crypto_rng_get_bytes / crypto_put_default_rng? > + > + if (vli_is_zero(priv, ndigits)) > + return -EINVAL; > + > + /* Make sure the private key is in the range [1, n-1]. */ > + if (vli_cmp(curve->n, priv, ndigits) != 1) > + return -EINVAL; > + > + ecc_swap_digits(priv, privkey, ndigits); Is a byteswap faster than a copy operation by looping through priv/privkey and simply assinging the value? > + > + return 0; > +} > + > int ecdh_make_pub_key(unsigned int curve_id, unsigned int ndigits, > const u8 *private_key, unsigned int private_key_len, > u8 *public_key, unsigned int public_key_len) > diff --git a/crypto/ecc.h b/crypto/ecc.h > index 663d598..b94b7ce 100644 > --- a/crypto/ecc.h > +++ b/crypto/ecc.h > @@ -44,6 +44,20 @@ int ecc_is_key_valid(unsigned int curve_id, unsigned int > ndigits, const u8 *private_key, unsigned int private_key_len); > > /** > + * ecc_gen_privkey() - Generates an ECC private key. > + * The private key is a random integer in the range 0 < random < n, where n > is a + * prime that is the order of the cyclic subgroup generated by the > distinguished + * point G. > + * @curve_id: id representing the curve to use > + * @ndigits: curve number of digits > + * @private_key: buffer for storing the generated private key > + * > + * Returns 0 if the private key was generated successfully, a negative > value + * if an error occurred. > + */ > +int ecc_gen_privkey(unsigned int curve_id, unsigned int ndigits, u64 > *privkey); + > +/** > * ecdh_make_pub_key() - Compute an ECC public key > * > * @curve_id: id representing the curve to use Ciao Stephan ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RFC PATCH v2 1/4] crypto: ecc - add privkey generation support 2017-05-28 18:44 ` Stephan Müller @ 2017-05-29 9:08 ` Tudor Ambarus 2017-05-29 9:23 ` Stephan Müller 0 siblings, 1 reply; 14+ messages in thread From: Tudor Ambarus @ 2017-05-29 9:08 UTC (permalink / raw) To: Stephan Müller; +Cc: herbert, davem, linux-crypto, marcel, Nicolas.Ferre Hi, Stephan, Thank you for the review. Please see inline. On 28.05.2017 21:44, Stephan Müller wrote: > Am Mittwoch, 17. Mai 2017, 17:26:50 CEST schrieb Tudor Ambarus: > > Hi Tudor, > >> Add support for generating ecc private keys. >> >> Generation of ecc private keys is helpful in a user-space to kernel >> ecdh offload because the keys are not revealed to user-space. Private >> key generation is also helpful to implement forward secrecy. >> >> Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com> >> --- >> crypto/ecc.c | 20 ++++++++++++++++++++ >> crypto/ecc.h | 14 ++++++++++++++ >> 2 files changed, 34 insertions(+) >> >> diff --git a/crypto/ecc.c b/crypto/ecc.c >> index 414c78a..a591907 100644 >> --- a/crypto/ecc.c >> +++ b/crypto/ecc.c >> @@ -927,6 +927,26 @@ int ecc_is_key_valid(unsigned int curve_id, unsigned >> int ndigits, return 0; >> } >> >> +int ecc_gen_privkey(unsigned int curve_id, unsigned int ndigits, u64 >> *privkey) +{ >> + const struct ecc_curve *curve = ecc_get_curve(curve_id); > > Shouldn't there be a check that a curve is selected? I.e. a check for an error > should be added? We already checked the curve_id before generating the key. The function assumes that curve_id is checked before calling it, like ecc_is_key_valid() does. > >> + u64 priv[ndigits]; > > Shouldn't there be a size check of ndigits? Already checked when setting the secret. But FIPS 186-4, B.4.1 recommends to check the bit length of n. It should be greater or equal with 160. I will add this check, thanks. > >> + unsigned int nbytes = ndigits << ECC_DIGITS_TO_BYTES_SHIFT; >> + >> + get_random_bytes(priv, nbytes); > > Can you please use crypto_get_default_rng / crypto_rng_get_bytes / > crypto_put_default_rng? Actually I tried this and I encountered some problems, I'm currently debugging it. When using the default rng and the run-time self tests are enabled, the kernel is in a blocking state. What's worse is that the kernel blocks before the console has the chance to be enabled and I can't see anything :). I suspect that the kernel blocks because the rng does not have enough entropy. Could you please give me some hints? >> + >> + if (vli_is_zero(priv, ndigits)) >> + return -EINVAL; >> + >> + /* Make sure the private key is in the range [1, n-1]. */ >> + if (vli_cmp(curve->n, priv, ndigits) != 1) >> + return -EINVAL; >> + >> + ecc_swap_digits(priv, privkey, ndigits); > > Is a byteswap faster than a copy operation by looping through priv/privkey and > simply assinging the value? Maybe not, but I am consistent with the rest of the code. Can we change this in a latter patch, if necessary? Thanks, ta ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RFC PATCH v2 1/4] crypto: ecc - add privkey generation support 2017-05-29 9:08 ` Tudor Ambarus @ 2017-05-29 9:23 ` Stephan Müller 2017-05-29 9:47 ` Tudor Ambarus 0 siblings, 1 reply; 14+ messages in thread From: Stephan Müller @ 2017-05-29 9:23 UTC (permalink / raw) To: Tudor Ambarus; +Cc: herbert, davem, linux-crypto, marcel, Nicolas.Ferre Am Montag, 29. Mai 2017, 11:08:38 CEST schrieb Tudor Ambarus: Hi Tudor, > > >> + unsigned int nbytes = ndigits << ECC_DIGITS_TO_BYTES_SHIFT; > >> + > >> + get_random_bytes(priv, nbytes); > > > > Can you please use crypto_get_default_rng / crypto_rng_get_bytes / > > crypto_put_default_rng? > > Actually I tried this and I encountered some problems, I'm currently > debugging it. > > When using the default rng and the run-time self tests are enabled, > the kernel is in a blocking state. What's worse is that the kernel > blocks before the console has the chance to be enabled and I can't see > anything :). > > I suspect that the kernel blocks because the rng does not have enough > entropy. Could you please give me some hints? Hm, there should be no blocking for the DRBG to initialize. What happens if you compile that as a module and insmod it at runtime? > > >> + > >> + if (vli_is_zero(priv, ndigits)) > >> + return -EINVAL; > >> + > >> + /* Make sure the private key is in the range [1, n-1]. */ > >> + if (vli_cmp(curve->n, priv, ndigits) != 1) > >> + return -EINVAL; > >> + > >> + ecc_swap_digits(priv, privkey, ndigits); > > > > Is a byteswap faster than a copy operation by looping through priv/privkey > > and simply assinging the value? > > Maybe not, but I am consistent with the rest of the code. Can we change > this in a latter patch, if necessary? Ok, fine with me. Ciao Stephan ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RFC PATCH v2 1/4] crypto: ecc - add privkey generation support 2017-05-29 9:23 ` Stephan Müller @ 2017-05-29 9:47 ` Tudor Ambarus 2017-05-29 9:56 ` Stephan Müller 0 siblings, 1 reply; 14+ messages in thread From: Tudor Ambarus @ 2017-05-29 9:47 UTC (permalink / raw) To: Stephan Müller; +Cc: herbert, davem, linux-crypto, marcel, Nicolas.Ferre Hi, Stephan, On 29.05.2017 12:23, Stephan Müller wrote: > Am Montag, 29. Mai 2017, 11:08:38 CEST schrieb Tudor Ambarus: > > Hi Tudor, >> >>>> + unsigned int nbytes = ndigits << ECC_DIGITS_TO_BYTES_SHIFT; >>>> + >>>> + get_random_bytes(priv, nbytes); >>> >>> Can you please use crypto_get_default_rng / crypto_rng_get_bytes / >>> crypto_put_default_rng? >> >> Actually I tried this and I encountered some problems, I'm currently >> debugging it. >> >> When using the default rng and the run-time self tests are enabled, >> the kernel is in a blocking state. What's worse is that the kernel >> blocks before the console has the chance to be enabled and I can't see >> anything :). >> >> I suspect that the kernel blocks because the rng does not have enough >> entropy. Could you please give me some hints? > > Hm, there should be no blocking for the DRBG to initialize. > > What happens if you compile that as a module and insmod it at runtime? We will have a nop: #ifdef CONFIG_CRYPTO_MANAGER_DISABLE_TESTS /* a perfect nop */ int alg_test(const char *driver, const char *alg, u32 type, u32 mask) { printk(KERN_ERR "no op in alg_test"); return 0; } #else ... #endif If I further mangle it and change #ifdef with #ifndef then the tests are passing. Thanks, ta ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RFC PATCH v2 1/4] crypto: ecc - add privkey generation support 2017-05-29 9:47 ` Tudor Ambarus @ 2017-05-29 9:56 ` Stephan Müller 2017-05-29 13:27 ` Tudor Ambarus 0 siblings, 1 reply; 14+ messages in thread From: Stephan Müller @ 2017-05-29 9:56 UTC (permalink / raw) To: Tudor Ambarus; +Cc: herbert, davem, linux-crypto, marcel, Nicolas.Ferre Am Montag, 29. Mai 2017, 11:47:48 CEST schrieb Tudor Ambarus: Hi Tudor, > > Hm, there should be no blocking for the DRBG to initialize. > > > > What happens if you compile that as a module and insmod it at runtime? > > We will have a nop: > > #ifdef CONFIG_CRYPTO_MANAGER_DISABLE_TESTS > > /* a perfect nop */ > int alg_test(const char *driver, const char *alg, u32 type, u32 mask) > { > printk(KERN_ERR "no op in alg_test"); > return 0; > } > > #else > ... > #endif > > If I further mangle it and change #ifdef with #ifndef then the tests are > passing. Can you please enable the testmgr in the kernel config and compile the DH/ECDH code as a module. Then I would insmod the dh/ecdh kernel module to see whether the self tests work or not. Note, if you use the calls of crypto_get_default_rng and friends, the DRBG must be present in the kernel at the time of calling. I.e. if you statically compile dh/ecdh but compile the RNG support as a module, the RNG will not load during self test. If you compile dh/ecdh as a module, the RNG can stay as a module. Ciao Stephan ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RFC PATCH v2 1/4] crypto: ecc - add privkey generation support 2017-05-29 9:56 ` Stephan Müller @ 2017-05-29 13:27 ` Tudor Ambarus 0 siblings, 0 replies; 14+ messages in thread From: Tudor Ambarus @ 2017-05-29 13:27 UTC (permalink / raw) To: Stephan Müller; +Cc: herbert, davem, linux-crypto, marcel, Nicolas.Ferre Hi, Stephan, On 29.05.2017 12:56, Stephan Müller wrote: > Am Montag, 29. Mai 2017, 11:47:48 CEST schrieb Tudor Ambarus: > > Hi Tudor, > >>> Hm, there should be no blocking for the DRBG to initialize. >>> >>> What happens if you compile that as a module and insmod it at runtime? >> >> We will have a nop: >> >> #ifdef CONFIG_CRYPTO_MANAGER_DISABLE_TESTS >> >> /* a perfect nop */ >> int alg_test(const char *driver, const char *alg, u32 type, u32 mask) >> { >> printk(KERN_ERR "no op in alg_test"); >> return 0; >> } >> >> #else >> ... >> #endif >> >> If I further mangle it and change #ifdef with #ifndef then the tests are >> passing. > > Can you please enable the testmgr in the kernel config and compile the DH/ECDH > code as a module. Then I would insmod the dh/ecdh kernel module to see whether > the self tests work or not. dh/ecdh self tests are passing when I insert dh/ecdh modules. > > Note, if you use the calls of crypto_get_default_rng and friends, the DRBG > must be present in the kernel at the time of calling. I.e. if you statically > compile dh/ecdh but compile the RNG support as a module, the RNG will not load > during self test. If you compile dh/ecdh as a module, the RNG can stay as a > module. However, when the self tests are enabled and DH/ECDH code is built-in, the kernel blocks. I have to ensure that the drivers are loaded in the right order. Deferring the probe or just simply changing the order of the object files from crypto/Makefile solves the issue. I'll go with the second approach. Thanks, ta ^ permalink raw reply [flat|nested] 14+ messages in thread
* [RFC PATCH v2 2/4] crypto: ecdh - allow user to provide NULL privkey 2017-05-17 15:26 [RFC PATCH v2 0/4] crypto: (ec)dh - add privkey generation support Tudor Ambarus 2017-05-17 15:26 ` [RFC PATCH v2 1/4] crypto: ecc " Tudor Ambarus @ 2017-05-17 15:26 ` Tudor Ambarus 2017-05-17 15:26 ` [RFC PATCH v2 3/4] crypto: dh " Tudor Ambarus 2017-05-17 15:26 ` [RFC PATCH v2 4/4] crypto: testmgr - add genkey kpp test Tudor Ambarus 3 siblings, 0 replies; 14+ messages in thread From: Tudor Ambarus @ 2017-05-17 15:26 UTC (permalink / raw) To: herbert, davem Cc: linux-crypto, smueller, marcel, Nicolas.Ferre, Tudor Ambarus If the user provides a NULL ecc private key, the kernel will generate it and further use it for ecdh. Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com> --- crypto/ecdh.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/crypto/ecdh.c b/crypto/ecdh.c index 63ca337..f28f5b5 100644 --- a/crypto/ecdh.c +++ b/crypto/ecdh.c @@ -55,6 +55,10 @@ static int ecdh_set_secret(struct crypto_kpp *tfm, const void *buf, ctx->curve_id = params.curve_id; ctx->ndigits = ndigits; + if (!params.key || !params.key_size) + return ecc_gen_privkey(ctx->curve_id, ctx->ndigits, + ctx->private_key); + if (ecc_is_key_valid(ctx->curve_id, ctx->ndigits, (const u8 *)params.key, params.key_size) < 0) return -EINVAL; -- 2.7.4 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* [RFC PATCH v2 3/4] crypto: dh - allow user to provide NULL privkey 2017-05-17 15:26 [RFC PATCH v2 0/4] crypto: (ec)dh - add privkey generation support Tudor Ambarus 2017-05-17 15:26 ` [RFC PATCH v2 1/4] crypto: ecc " Tudor Ambarus 2017-05-17 15:26 ` [RFC PATCH v2 2/4] crypto: ecdh - allow user to provide NULL privkey Tudor Ambarus @ 2017-05-17 15:26 ` Tudor Ambarus 2017-05-28 18:50 ` Stephan Müller 2017-05-17 15:26 ` [RFC PATCH v2 4/4] crypto: testmgr - add genkey kpp test Tudor Ambarus 3 siblings, 1 reply; 14+ messages in thread From: Tudor Ambarus @ 2017-05-17 15:26 UTC (permalink / raw) To: herbert, davem Cc: linux-crypto, smueller, marcel, Nicolas.Ferre, Tudor Ambarus If the user provides a NULL private key, the kernel will generate it and further use it for dh. Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com> --- crypto/dh.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/crypto/dh.c b/crypto/dh.c index 87e3542..7b4ac5b 100644 --- a/crypto/dh.c +++ b/crypto/dh.c @@ -83,7 +83,9 @@ static int dh_set_secret(struct crypto_kpp *tfm, const void *buf, unsigned int len) { struct dh_ctx *ctx = dh_get_ctx(tfm); + u8 *rndbuf = NULL; struct dh params; + int maxsize; if (crypto_dh_decode_key(buf, len, ¶ms) < 0) return -EINVAL; @@ -91,7 +93,26 @@ static int dh_set_secret(struct crypto_kpp *tfm, const void *buf, if (dh_set_params(ctx, ¶ms) < 0) return -EINVAL; + if (!params.key || !params.key_size) { + maxsize = crypto_kpp_maxsize(tfm); + if (maxsize < 0) { + dh_clear_params(ctx); + return maxsize; + } + + rndbuf = kmalloc(maxsize, GFP_KERNEL); + if (!rndbuf) { + dh_clear_params(ctx); + return -ENOMEM; + } + + get_random_bytes(rndbuf, maxsize); + params.key = rndbuf; + params.key_size = maxsize; + } + ctx->xa = mpi_read_raw_data(params.key, params.key_size); + kzfree(rndbuf); if (!ctx->xa) { dh_clear_params(ctx); return -EINVAL; -- 2.7.4 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [RFC PATCH v2 3/4] crypto: dh - allow user to provide NULL privkey 2017-05-17 15:26 ` [RFC PATCH v2 3/4] crypto: dh " Tudor Ambarus @ 2017-05-28 18:50 ` Stephan Müller 0 siblings, 0 replies; 14+ messages in thread From: Stephan Müller @ 2017-05-28 18:50 UTC (permalink / raw) To: Tudor Ambarus; +Cc: herbert, davem, linux-crypto, marcel, Nicolas.Ferre Am Mittwoch, 17. Mai 2017, 17:26:52 CEST schrieb Tudor Ambarus: Hi Tudor, > If the user provides a NULL private key, the kernel will > generate it and further use it for dh. > > Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com> > --- > crypto/dh.c | 21 +++++++++++++++++++++ > 1 file changed, 21 insertions(+) > > diff --git a/crypto/dh.c b/crypto/dh.c > index 87e3542..7b4ac5b 100644 > --- a/crypto/dh.c > +++ b/crypto/dh.c > @@ -83,7 +83,9 @@ static int dh_set_secret(struct crypto_kpp *tfm, const > void *buf, unsigned int len) > { > struct dh_ctx *ctx = dh_get_ctx(tfm); > + u8 *rndbuf = NULL; > struct dh params; > + int maxsize; > > if (crypto_dh_decode_key(buf, len, ¶ms) < 0) > return -EINVAL; > @@ -91,7 +93,26 @@ static int dh_set_secret(struct crypto_kpp *tfm, const > void *buf, if (dh_set_params(ctx, ¶ms) < 0) > return -EINVAL; > > + if (!params.key || !params.key_size) { > + maxsize = crypto_kpp_maxsize(tfm); > + if (maxsize < 0) { > + dh_clear_params(ctx); > + return maxsize; > + } > + > + rndbuf = kmalloc(maxsize, GFP_KERNEL); > + if (!rndbuf) { > + dh_clear_params(ctx); > + return -ENOMEM; > + } > + > + get_random_bytes(rndbuf, maxsize); Could you please use again the kernel crypto API RNG as mentioned for ECC? > + params.key = rndbuf; > + params.key_size = maxsize; > + } > + > ctx->xa = mpi_read_raw_data(params.key, params.key_size); > + kzfree(rndbuf); > if (!ctx->xa) { > dh_clear_params(ctx); > return -EINVAL; Ciao Stephan ^ permalink raw reply [flat|nested] 14+ messages in thread
* [RFC PATCH v2 4/4] crypto: testmgr - add genkey kpp test 2017-05-17 15:26 [RFC PATCH v2 0/4] crypto: (ec)dh - add privkey generation support Tudor Ambarus ` (2 preceding siblings ...) 2017-05-17 15:26 ` [RFC PATCH v2 3/4] crypto: dh " Tudor Ambarus @ 2017-05-17 15:26 ` Tudor Ambarus 2017-05-26 13:44 ` Tudor Ambarus 2017-05-28 18:57 ` Stephan Müller 3 siblings, 2 replies; 14+ messages in thread From: Tudor Ambarus @ 2017-05-17 15:26 UTC (permalink / raw) To: herbert, davem Cc: linux-crypto, smueller, marcel, Nicolas.Ferre, Tudor Ambarus The test considers a party that already has a private-public key pair and a party that provides a NULL key. The kernel will generate the private-public key pair for the latter, computes the shared secret on both ends and verifies it it's the same. The explicit private-public key pairs were copied from the previous test vectors. Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com> --- crypto/testmgr.c | 76 +++++++++++++++++++++++---- crypto/testmgr.h | 155 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 220 insertions(+), 11 deletions(-) diff --git a/crypto/testmgr.c b/crypto/testmgr.c index 6f5f3ed..faf5fd8 100644 --- a/crypto/testmgr.c +++ b/crypto/testmgr.c @@ -1997,6 +1997,9 @@ static int do_test_kpp(struct crypto_kpp *tfm, const struct kpp_testvec *vec, struct kpp_request *req; void *input_buf = NULL; void *output_buf = NULL; + void *a_public = NULL; + void *a_ss = NULL; + void *shared_secret = NULL; struct tcrypt_result result; unsigned int out_len_max; int err = -ENOMEM; @@ -2026,20 +2029,31 @@ static int do_test_kpp(struct crypto_kpp *tfm, const struct kpp_testvec *vec, kpp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, tcrypt_complete, &result); - /* Compute public key */ + /* Compute party A's public key */ err = wait_async_op(&result, crypto_kpp_generate_public_key(req)); if (err) { - pr_err("alg: %s: generate public key test failed. err %d\n", + pr_err("alg: %s: Party A: generate public key test failed. err %d\n", alg, err); goto free_output; } - /* Verify calculated public key */ - if (memcmp(vec->expected_a_public, sg_virt(req->dst), - vec->expected_a_public_size)) { - pr_err("alg: %s: generate public key test failed. Invalid output\n", - alg); - err = -EINVAL; - goto free_output; + + if (vec->genkey) { + /* Save party A's public key */ + a_public = kzalloc(out_len_max, GFP_KERNEL); + if (!a_public) { + err = -ENOMEM; + goto free_output; + } + memcpy(a_public, sg_virt(req->dst), sizeof(*a_public)); + } else { + /* Verify calculated public key */ + if (memcmp(vec->expected_a_public, sg_virt(req->dst), + vec->expected_a_public_size)) { + pr_err("alg: %s: Party A: generate public key test failed. Invalid output\n", + alg); + err = -EINVAL; + goto free_output; + } } /* Calculate shared secret key by using counter part (b) public key. */ @@ -2058,15 +2072,53 @@ static int do_test_kpp(struct crypto_kpp *tfm, const struct kpp_testvec *vec, tcrypt_complete, &result); err = wait_async_op(&result, crypto_kpp_compute_shared_secret(req)); if (err) { - pr_err("alg: %s: compute shard secret test failed. err %d\n", + pr_err("alg: %s: Party A: compute shared secret test failed. err %d\n", alg, err); goto free_all; } + + if (vec->genkey) { + /* Save the shared secret obtained by party A */ + a_ss = kzalloc(vec->expected_ss_size, GFP_KERNEL); + if (!a_ss) { + err = -ENOMEM; + goto free_all; + } + memcpy(a_ss, sg_virt(req->dst), sizeof(*a_ss)); + + /* + * Calculate party B's shared secret by using party A's + * public key. + */ + err = crypto_kpp_set_secret(tfm, vec->b_secret, + vec->b_secret_size); + if (err < 0) + goto free_all; + + sg_init_one(&src, a_public, vec->expected_a_public_size); + sg_init_one(&dst, output_buf, out_len_max); + kpp_request_set_input(req, &src, vec->expected_a_public_size); + kpp_request_set_output(req, &dst, out_len_max); + kpp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, + tcrypt_complete, &result); + err = wait_async_op(&result, + crypto_kpp_compute_shared_secret(req)); + if (err) { + pr_err("alg: %s: Party B: compute shared secret failed. err %d\n", + alg, err); + goto free_all; + } + + shared_secret = a_ss; + } else { + shared_secret = (void *)vec->expected_ss; + } + /* * verify shared secret from which the user will derive * secret key by executing whatever hash it has chosen */ - if (memcmp(vec->expected_ss, sg_virt(req->dst), + if (memcmp(shared_secret, sg_virt(req->dst), vec->expected_ss_size)) { pr_err("alg: %s: compute shared secret test failed. Invalid output\n", alg); @@ -2074,8 +2126,10 @@ static int do_test_kpp(struct crypto_kpp *tfm, const struct kpp_testvec *vec, } free_all: + kfree(a_ss); kfree(input_buf); free_output: + kfree(a_public); kfree(output_buf); free_req: kpp_request_free(req); diff --git a/crypto/testmgr.h b/crypto/testmgr.h index 4293573..a6c6b24 100644 --- a/crypto/testmgr.h +++ b/crypto/testmgr.h @@ -137,13 +137,16 @@ struct akcipher_testvec { struct kpp_testvec { const unsigned char *secret; + const unsigned char *b_secret; const unsigned char *b_public; const unsigned char *expected_a_public; const unsigned char *expected_ss; unsigned short secret_size; + unsigned short b_secret_size; unsigned short b_public_size; unsigned short expected_a_public_size; unsigned short expected_ss_size; + bool genkey; }; static const char zeroed_string[48]; @@ -752,6 +755,114 @@ static const struct kpp_testvec dh_tv_template[] = { .b_public_size = 256, .expected_a_public_size = 256, .expected_ss_size = 256, + }, + { + .secret = +#ifdef __LITTLE_ENDIAN + "\x01\x00" /* type */ + "\x11\x01" /* len */ + "\x00\x00\x00\x00" /* key_size */ + "\x00\x01\x00\x00" /* p_size */ + "\x01\x00\x00\x00" /* g_size */ +#else + "\x00\x01" /* type */ + "\x01\x11" /* len */ + "\x00\x00\x00\x00" /* key_size */ + "\x00\x00\x01\x00" /* p_size */ + "\x00\x00\x00\x01" /* g_size */ +#endif + /* p */ + "\xb9\x36\x3a\xf1\x82\x1f\x60\xd3\x22\x47\xb8\xbc\x2d\x22\x6b\x81" + "\x7f\xe8\x20\x06\x09\x23\x73\x49\x9a\x59\x8b\x35\x25\xf8\x31\xbc" + "\x7d\xa8\x1c\x9d\x56\x0d\x1a\xf7\x4b\x4f\x96\xa4\x35\x77\x6a\x89" + "\xab\x42\x00\x49\x21\x71\xed\x28\x16\x1d\x87\x5a\x10\xa7\x9c\x64" + "\x94\xd4\x87\x3d\x28\xef\x44\xfe\x4b\xe2\xb4\x15\x8c\x82\xa6\xf3" + "\x50\x5f\xa8\xe8\xa2\x60\xe7\x00\x86\x78\x05\xd4\x78\x19\xa1\x98" + "\x62\x4e\x4a\x00\x78\x56\x96\xe6\xcf\xd7\x10\x1b\x74\x5d\xd0\x26" + "\x61\xdb\x6b\x32\x09\x51\xd8\xa5\xfd\x54\x16\x71\x01\xb3\x39\xe6" + "\x4e\x69\xb1\xd7\x06\x8f\xd6\x1e\xdc\x72\x25\x26\x74\xc8\x41\x06" + "\x5c\xd1\x26\x5c\xb0\x2f\xf9\x59\x13\xc1\x2a\x0f\x78\xea\x7b\xf7" + "\xbd\x59\xa0\x90\x1d\xfc\x33\x5b\x4c\xbf\x05\x9c\x3a\x3f\x69\xa2" + "\x45\x61\x4e\x10\x6a\xb3\x17\xc5\x68\x30\xfb\x07\x5f\x34\xc6\xfb" + "\x73\x07\x3c\x70\xf6\xae\xe7\x72\x84\xc3\x18\x81\x8f\xe8\x11\x1f" + "\x3d\x83\x83\x01\x2a\x14\x73\xbf\x32\x32\x2e\xc9\x4d\xdb\x2a\xca" + "\xee\x71\xf9\xda\xad\xe8\x82\x0b\x4d\x0c\x1f\xb6\x1d\xef\x00\x67" + "\x74\x3d\x95\xe0\xb7\xc4\x30\x8a\x24\x87\x12\x47\x27\x70\x0d\x73" + /* g */ + "\x02", + .b_secret = +#ifdef __LITTLE_ENDIAN + "\x01\x00" /* type */ + "\x11\x02" /* len */ + "\x00\x01\x00\x00" /* key_size */ + "\x00\x01\x00\x00" /* p_size */ + "\x01\x00\x00\x00" /* g_size */ +#else + "\x00\x01" /* type */ + "\x02\x11" /* len */ + "\x00\x00\x01\x00" /* key_size */ + "\x00\x00\x01\x00" /* p_size */ + "\x00\x00\x00\x01" /* g_size */ +#endif + /* xa */ + "\x4d\x75\xa8\x6e\xba\x23\x3a\x0c\x63\x56\xc8\xc9\x5a\xa7\xd6\x0e" + "\xed\xae\x40\x78\x87\x47\x5f\xe0\xa7\x7b\xba\x84\x88\x67\x4e\xe5" + "\x3c\xcc\x5c\x6a\xe7\x4a\x20\xec\xbe\xcb\xf5\x52\x62\x9f\x37\x80" + "\x0c\x72\x7b\x83\x66\xa4\xf6\x7f\x95\x97\x1c\x6a\x5c\x7e\xf1\x67" + "\x37\xb3\x93\x39\x3d\x0b\x55\x35\xd9\xe5\x22\x04\x9f\xf8\xc1\x04" + "\xce\x13\xa5\xac\xe1\x75\x05\xd1\x2b\x53\xa2\x84\xef\xb1\x18\xf4" + "\x66\xdd\xea\xe6\x24\x69\x5a\x49\xe0\x7a\xd8\xdf\x1b\xb7\xf1\x6d" + "\x9b\x50\x2c\xc8\x1c\x1c\xa3\xb4\x37\xfb\x66\x3f\x67\x71\x73\xa9" + "\xff\x5f\xd9\xa2\x25\x6e\x25\x1b\x26\x54\xbf\x0c\xc6\xdb\xea\x0a" + "\x52\x6c\x16\x7c\x27\x68\x15\x71\x58\x73\x9d\xe6\xc2\x80\xaa\x97" + "\x31\x66\xfb\xa6\xfb\xfd\xd0\x9c\x1d\xbe\x81\x48\xf5\x9a\x32\xf1" + "\x69\x62\x18\x78\xae\x72\x36\xe6\x94\x27\xd1\xff\x18\x4f\x28\x6a" + "\x16\xbd\x6a\x60\xee\xe5\xf9\x6d\x16\xe4\xb8\xa6\x41\x9b\x23\x7e" + "\xf7\x9d\xd1\x1d\x03\x15\x66\x3a\xcf\xb6\x2c\x13\x96\x2c\x52\x21" + "\xe4\x2d\x48\x7a\x8a\x5d\xb2\x88\xed\x98\x61\x79\x8b\x6a\x1e\x5f" + "\xd0\x8a\x2d\x99\x5a\x2b\x0f\xbc\xef\x53\x8f\x32\xc1\xa2\x99\x26" + /* p */ + "\xb9\x36\x3a\xf1\x82\x1f\x60\xd3\x22\x47\xb8\xbc\x2d\x22\x6b\x81" + "\x7f\xe8\x20\x06\x09\x23\x73\x49\x9a\x59\x8b\x35\x25\xf8\x31\xbc" + "\x7d\xa8\x1c\x9d\x56\x0d\x1a\xf7\x4b\x4f\x96\xa4\x35\x77\x6a\x89" + "\xab\x42\x00\x49\x21\x71\xed\x28\x16\x1d\x87\x5a\x10\xa7\x9c\x64" + "\x94\xd4\x87\x3d\x28\xef\x44\xfe\x4b\xe2\xb4\x15\x8c\x82\xa6\xf3" + "\x50\x5f\xa8\xe8\xa2\x60\xe7\x00\x86\x78\x05\xd4\x78\x19\xa1\x98" + "\x62\x4e\x4a\x00\x78\x56\x96\xe6\xcf\xd7\x10\x1b\x74\x5d\xd0\x26" + "\x61\xdb\x6b\x32\x09\x51\xd8\xa5\xfd\x54\x16\x71\x01\xb3\x39\xe6" + "\x4e\x69\xb1\xd7\x06\x8f\xd6\x1e\xdc\x72\x25\x26\x74\xc8\x41\x06" + "\x5c\xd1\x26\x5c\xb0\x2f\xf9\x59\x13\xc1\x2a\x0f\x78\xea\x7b\xf7" + "\xbd\x59\xa0\x90\x1d\xfc\x33\x5b\x4c\xbf\x05\x9c\x3a\x3f\x69\xa2" + "\x45\x61\x4e\x10\x6a\xb3\x17\xc5\x68\x30\xfb\x07\x5f\x34\xc6\xfb" + "\x73\x07\x3c\x70\xf6\xae\xe7\x72\x84\xc3\x18\x81\x8f\xe8\x11\x1f" + "\x3d\x83\x83\x01\x2a\x14\x73\xbf\x32\x32\x2e\xc9\x4d\xdb\x2a\xca" + "\xee\x71\xf9\xda\xad\xe8\x82\x0b\x4d\x0c\x1f\xb6\x1d\xef\x00\x67" + "\x74\x3d\x95\xe0\xb7\xc4\x30\x8a\x24\x87\x12\x47\x27\x70\x0d\x73" + /* g */ + "\x02", + .b_public = + "\x90\x89\xe4\x82\xd6\x0a\xcf\x1a\xae\xce\x1b\x66\xa7\x19\x71\x18" + "\x8f\x95\x4b\x5b\x80\x45\x4a\x5a\x43\x99\x4d\x37\xcf\xa3\xa7\x28" + "\x9c\xc7\x73\xf1\xb2\x17\xf6\x99\xe3\x6b\x56\xcb\x3e\x35\x60\x7d" + "\x65\xc7\x84\x6b\x3e\x60\xee\xcd\xd2\x70\xe7\xc9\x32\x1c\xf0\xb4" + "\xf9\x52\xd9\x88\x75\xfd\x40\x2c\xa7\xbe\x19\x1c\x0a\xae\x93\xe1" + "\x71\xc7\xcd\x4f\x33\x5c\x10\x7d\x39\x56\xfc\x73\x84\xb2\x67\xc3" + "\x77\x26\x20\x97\x2b\xf8\x13\x43\x93\x9c\x9a\xa4\x08\xc7\x34\x83" + "\xe6\x98\x61\xe7\x16\x30\x2c\xb1\xdb\x2a\xb2\xcc\xc3\x02\xa5\x3c" + "\x71\x50\x14\x83\xc7\xbb\xa4\xbe\x98\x1b\xfe\xcb\x43\xe9\x97\x62" + "\xd6\xf0\x8c\xcb\x1c\xba\x1e\xa8\xa6\xa6\x50\xfc\x85\x7d\x47\xbf" + "\xf4\x3e\x23\xd3\x5f\xb2\x71\x3e\x40\x94\xaa\x87\x83\x2c\x6c\x8e" + "\x60\xfd\xdd\xf7\xf4\x76\x03\xd3\x1d\xec\x18\x51\xa3\xf2\x44\x1a" + "\x3f\xb4\x7c\x18\x0d\x68\x65\x92\x54\x0d\x2d\x81\x16\xf1\x84\x66" + "\x89\x92\xd0\x1a\x5e\x1f\x42\x46\x5b\xe5\x83\x86\x80\xd9\xcd\x3a" + "\x5a\x2f\xb9\x59\x9b\xe4\x43\x84\x64\xf3\x09\x1a\x0a\xa2\x64\x0f" + "\x77\x4e\x8d\x8b\xe6\x88\xd1\xfc\xaf\x8f\xdf\x1d\xbc\x31\xb3\xbd", + .secret_size = 273, + .b_secret_size = 529, + .b_public_size = 256, + .expected_a_public_size = 256, + .expected_ss_size = 256, + .genkey = true, } }; @@ -840,6 +951,50 @@ static const struct kpp_testvec ecdh_tv_template[] = { .b_public_size = 64, .expected_a_public_size = 64, .expected_ss_size = 32 + }, { + .secret = +#ifdef __LITTLE_ENDIAN + "\x02\x00" /* type */ + "\x08\x00" /* len */ + "\x02\x00" /* curve_id */ + "\x00\x00", /* key_size */ +#else + "\x00\x02" /* type */ + "\x00\x08" /* len */ + "\x00\x02" /* curve_id */ + "\x00\x00", /* key_size */ +#endif + .b_secret = +#ifdef __LITTLE_ENDIAN + "\x02\x00" /* type */ + "\x28\x00" /* len */ + "\x02\x00" /* curve_id */ + "\x20\x00" /* key_size */ +#else + "\x00\x02" /* type */ + "\x00\x28" /* len */ + "\x00\x02" /* curve_id */ + "\x00\x20" /* key_size */ +#endif + "\x24\xd1\x21\xeb\xe5\xcf\x2d\x83" + "\xf6\x62\x1b\x6e\x43\x84\x3a\xa3" + "\x8b\xe0\x86\xc3\x20\x19\xda\x92" + "\x50\x53\x03\xe1\xc0\xea\xb8\x82", + .b_public = + "\x1a\x7f\xeb\x52\x00\xbd\x3c\x31" + "\x7d\xb6\x70\xc1\x86\xa6\xc7\xc4" + "\x3b\xc5\x5f\x6c\x6f\x58\x3c\xf5" + "\xb6\x63\x82\x77\x33\x24\xa1\x5f" + "\x6a\xca\x43\x6f\xf7\x7e\xff\x02" + "\x37\x08\xcc\x40\x5e\x7a\xfd\x6a" + "\x6a\x02\x6e\x41\x87\x68\x38\x77" + "\xfa\xa9\x44\x43\x2d\xef\x09\xdf", + .secret_size = 8, + .b_secret_size = 40, + .b_public_size = 64, + .expected_a_public_size = 64, + .expected_ss_size = 32, + .genkey = true, } }; -- 2.7.4 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [RFC PATCH v2 4/4] crypto: testmgr - add genkey kpp test 2017-05-17 15:26 ` [RFC PATCH v2 4/4] crypto: testmgr - add genkey kpp test Tudor Ambarus @ 2017-05-26 13:44 ` Tudor Ambarus 2017-05-28 18:57 ` Stephan Müller 1 sibling, 0 replies; 14+ messages in thread From: Tudor Ambarus @ 2017-05-26 13:44 UTC (permalink / raw) To: herbert, davem; +Cc: linux-crypto, smueller, marcel, Nicolas.Ferre On 17.05.2017 18:26, Tudor Ambarus wrote: > The test considers a party that already has a private-public > key pair and a party that provides a NULL key. The kernel will > generate the private-public key pair for the latter, computes > the shared secret on both ends and verifies it it's the same. > > The explicit private-public key pairs were copied from > the previous test vectors. > > Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com> > --- > crypto/testmgr.c | 76 +++++++++++++++++++++++---- > crypto/testmgr.h | 155 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 220 insertions(+), 11 deletions(-) > > diff --git a/crypto/testmgr.c b/crypto/testmgr.c > index 6f5f3ed..faf5fd8 100644 > --- a/crypto/testmgr.c > +++ b/crypto/testmgr.c > @@ -1997,6 +1997,9 @@ static int do_test_kpp(struct crypto_kpp *tfm, const struct kpp_testvec *vec, > struct kpp_request *req; > void *input_buf = NULL; > void *output_buf = NULL; > + void *a_public = NULL; > + void *a_ss = NULL; > + void *shared_secret = NULL; > struct tcrypt_result result; > unsigned int out_len_max; > int err = -ENOMEM; > @@ -2026,20 +2029,31 @@ static int do_test_kpp(struct crypto_kpp *tfm, const struct kpp_testvec *vec, > kpp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, > tcrypt_complete, &result); > > - /* Compute public key */ > + /* Compute party A's public key */ > err = wait_async_op(&result, crypto_kpp_generate_public_key(req)); > if (err) { > - pr_err("alg: %s: generate public key test failed. err %d\n", > + pr_err("alg: %s: Party A: generate public key test failed. err %d\n", > alg, err); > goto free_output; > } > - /* Verify calculated public key */ > - if (memcmp(vec->expected_a_public, sg_virt(req->dst), > - vec->expected_a_public_size)) { > - pr_err("alg: %s: generate public key test failed. Invalid output\n", > - alg); > - err = -EINVAL; > - goto free_output; > + > + if (vec->genkey) { > + /* Save party A's public key */ > + a_public = kzalloc(out_len_max, GFP_KERNEL); > + if (!a_public) { > + err = -ENOMEM; > + goto free_output; > + } > + memcpy(a_public, sg_virt(req->dst), sizeof(*a_public)); The size is wrong, I'll correct it in the next version. ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RFC PATCH v2 4/4] crypto: testmgr - add genkey kpp test 2017-05-17 15:26 ` [RFC PATCH v2 4/4] crypto: testmgr - add genkey kpp test Tudor Ambarus 2017-05-26 13:44 ` Tudor Ambarus @ 2017-05-28 18:57 ` Stephan Müller 1 sibling, 0 replies; 14+ messages in thread From: Stephan Müller @ 2017-05-28 18:57 UTC (permalink / raw) To: Tudor Ambarus; +Cc: herbert, davem, linux-crypto, marcel, Nicolas.Ferre Am Mittwoch, 17. Mai 2017, 17:26:53 CEST schrieb Tudor Ambarus: Hi Tudor, > The test considers a party that already has a private-public > key pair and a party that provides a NULL key. The kernel will > generate the private-public key pair for the latter, computes > the shared secret on both ends and verifies it it's the same. > > The explicit private-public key pairs were copied from > the previous test vectors. > > Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com> > --- > crypto/testmgr.c | 76 +++++++++++++++++++++++---- > crypto/testmgr.h | 155 > +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, > 220 insertions(+), 11 deletions(-) > > diff --git a/crypto/testmgr.c b/crypto/testmgr.c > index 6f5f3ed..faf5fd8 100644 > --- a/crypto/testmgr.c > +++ b/crypto/testmgr.c > @@ -1997,6 +1997,9 @@ static int do_test_kpp(struct crypto_kpp *tfm, const > struct kpp_testvec *vec, struct kpp_request *req; > void *input_buf = NULL; > void *output_buf = NULL; > + void *a_public = NULL; > + void *a_ss = NULL; > + void *shared_secret = NULL; > struct tcrypt_result result; > unsigned int out_len_max; > int err = -ENOMEM; > @@ -2026,20 +2029,31 @@ static int do_test_kpp(struct crypto_kpp *tfm, const > struct kpp_testvec *vec, kpp_request_set_callback(req, > CRYPTO_TFM_REQ_MAY_BACKLOG, > tcrypt_complete, &result); > > - /* Compute public key */ > + /* Compute party A's public key */ > err = wait_async_op(&result, crypto_kpp_generate_public_key(req)); > if (err) { > - pr_err("alg: %s: generate public key test failed. err %d\n", > + pr_err("alg: %s: Party A: generate public key test failed. err %d\n", > alg, err); > goto free_output; > } > - /* Verify calculated public key */ > - if (memcmp(vec->expected_a_public, sg_virt(req->dst), > - vec->expected_a_public_size)) { > - pr_err("alg: %s: generate public key test failed. Invalid output\n", > - alg); > - err = -EINVAL; > - goto free_output; > + > + if (vec->genkey) { > + /* Save party A's public key */ > + a_public = kzalloc(out_len_max, GFP_KERNEL); > + if (!a_public) { > + err = -ENOMEM; > + goto free_output; > + } > + memcpy(a_public, sg_virt(req->dst), sizeof(*a_public)); As you mentioned, sizeof() may not be the right length. > + } else { > + /* Verify calculated public key */ > + if (memcmp(vec->expected_a_public, sg_virt(req->dst), > + vec->expected_a_public_size)) { > + pr_err("alg: %s: Party A: generate public key test failed. Invalid > output\n", + alg); > + err = -EINVAL; > + goto free_output; > + } > } > > /* Calculate shared secret key by using counter part (b) public key. */ > @@ -2058,15 +2072,53 @@ static int do_test_kpp(struct crypto_kpp *tfm, const > struct kpp_testvec *vec, tcrypt_complete, &result); > err = wait_async_op(&result, crypto_kpp_compute_shared_secret(req)); > if (err) { > - pr_err("alg: %s: compute shard secret test failed. err %d\n", > + pr_err("alg: %s: Party A: compute shared secret test failed. err %d \n", > alg, err); > goto free_all; > } > + > + if (vec->genkey) { > + /* Save the shared secret obtained by party A */ > + a_ss = kzalloc(vec->expected_ss_size, GFP_KERNEL); > + if (!a_ss) { > + err = -ENOMEM; > + goto free_all; > + } > + memcpy(a_ss, sg_virt(req->dst), sizeof(*a_ss)); Same here, sizeof(void *)? > + > + /* > + * Calculate party B's shared secret by using party A's > + * public key. > + */ > + err = crypto_kpp_set_secret(tfm, vec->b_secret, > + vec->b_secret_size); > + if (err < 0) > + goto free_all; > + > + sg_init_one(&src, a_public, vec->expected_a_public_size); > + sg_init_one(&dst, output_buf, out_len_max); > + kpp_request_set_input(req, &src, vec->expected_a_public_size); > + kpp_request_set_output(req, &dst, out_len_max); > + kpp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, > + tcrypt_complete, &result); > + err = wait_async_op(&result, > + crypto_kpp_compute_shared_secret(req)); > + if (err) { > + pr_err("alg: %s: Party B: compute shared secret failed. err %d\n", > + alg, err); > + goto free_all; > + } > + > + shared_secret = a_ss; > + } else { > + shared_secret = (void *)vec->expected_ss; > + } > + > /* > * verify shared secret from which the user will derive > * secret key by executing whatever hash it has chosen > */ > - if (memcmp(vec->expected_ss, sg_virt(req->dst), > + if (memcmp(shared_secret, sg_virt(req->dst), > vec->expected_ss_size)) { > pr_err("alg: %s: compute shared secret test failed. Invalid output\n", > alg); > @@ -2074,8 +2126,10 @@ static int do_test_kpp(struct crypto_kpp *tfm, const > struct kpp_testvec *vec, } > > free_all: > + kfree(a_ss); > kfree(input_buf); > free_output: > + kfree(a_public); > kfree(output_buf); > free_req: > kpp_request_free(req); > diff --git a/crypto/testmgr.h b/crypto/testmgr.h > index 4293573..a6c6b24 100644 > --- a/crypto/testmgr.h > +++ b/crypto/testmgr.h > @@ -137,13 +137,16 @@ struct akcipher_testvec { > > struct kpp_testvec { > const unsigned char *secret; > + const unsigned char *b_secret; > const unsigned char *b_public; > const unsigned char *expected_a_public; > const unsigned char *expected_ss; > unsigned short secret_size; > + unsigned short b_secret_size; > unsigned short b_public_size; > unsigned short expected_a_public_size; > unsigned short expected_ss_size; > + bool genkey; > }; > > static const char zeroed_string[48]; > @@ -752,6 +755,114 @@ static const struct kpp_testvec dh_tv_template[] = { > .b_public_size = 256, > .expected_a_public_size = 256, > .expected_ss_size = 256, > + }, > + { > + .secret = > +#ifdef __LITTLE_ENDIAN > + "\x01\x00" /* type */ > + "\x11\x01" /* len */ > + "\x00\x00\x00\x00" /* key_size */ > + "\x00\x01\x00\x00" /* p_size */ > + "\x01\x00\x00\x00" /* g_size */ > +#else > + "\x00\x01" /* type */ > + "\x01\x11" /* len */ > + "\x00\x00\x00\x00" /* key_size */ > + "\x00\x00\x01\x00" /* p_size */ > + "\x00\x00\x00\x01" /* g_size */ > +#endif > + /* p */ > + "\xb9\x36\x3a\xf1\x82\x1f\x60\xd3\x22\x47\xb8\xbc\x2d\x22\x6b\x81" > + "\x7f\xe8\x20\x06\x09\x23\x73\x49\x9a\x59\x8b\x35\x25\xf8\x31\xbc" > + "\x7d\xa8\x1c\x9d\x56\x0d\x1a\xf7\x4b\x4f\x96\xa4\x35\x77\x6a\x89" > + "\xab\x42\x00\x49\x21\x71\xed\x28\x16\x1d\x87\x5a\x10\xa7\x9c\x64" > + "\x94\xd4\x87\x3d\x28\xef\x44\xfe\x4b\xe2\xb4\x15\x8c\x82\xa6\xf3" > + "\x50\x5f\xa8\xe8\xa2\x60\xe7\x00\x86\x78\x05\xd4\x78\x19\xa1\x98" > + "\x62\x4e\x4a\x00\x78\x56\x96\xe6\xcf\xd7\x10\x1b\x74\x5d\xd0\x26" > + "\x61\xdb\x6b\x32\x09\x51\xd8\xa5\xfd\x54\x16\x71\x01\xb3\x39\xe6" > + "\x4e\x69\xb1\xd7\x06\x8f\xd6\x1e\xdc\x72\x25\x26\x74\xc8\x41\x06" > + "\x5c\xd1\x26\x5c\xb0\x2f\xf9\x59\x13\xc1\x2a\x0f\x78\xea\x7b\xf7" > + "\xbd\x59\xa0\x90\x1d\xfc\x33\x5b\x4c\xbf\x05\x9c\x3a\x3f\x69\xa2" > + "\x45\x61\x4e\x10\x6a\xb3\x17\xc5\x68\x30\xfb\x07\x5f\x34\xc6\xfb" > + "\x73\x07\x3c\x70\xf6\xae\xe7\x72\x84\xc3\x18\x81\x8f\xe8\x11\x1f" > + "\x3d\x83\x83\x01\x2a\x14\x73\xbf\x32\x32\x2e\xc9\x4d\xdb\x2a\xca" > + "\xee\x71\xf9\xda\xad\xe8\x82\x0b\x4d\x0c\x1f\xb6\x1d\xef\x00\x67" > + "\x74\x3d\x95\xe0\xb7\xc4\x30\x8a\x24\x87\x12\x47\x27\x70\x0d\x73" > + /* g */ > + "\x02", > + .b_secret = > +#ifdef __LITTLE_ENDIAN > + "\x01\x00" /* type */ > + "\x11\x02" /* len */ > + "\x00\x01\x00\x00" /* key_size */ > + "\x00\x01\x00\x00" /* p_size */ > + "\x01\x00\x00\x00" /* g_size */ > +#else > + "\x00\x01" /* type */ > + "\x02\x11" /* len */ > + "\x00\x00\x01\x00" /* key_size */ > + "\x00\x00\x01\x00" /* p_size */ > + "\x00\x00\x00\x01" /* g_size */ > +#endif > + /* xa */ > + "\x4d\x75\xa8\x6e\xba\x23\x3a\x0c\x63\x56\xc8\xc9\x5a\xa7\xd6\x0e" > + "\xed\xae\x40\x78\x87\x47\x5f\xe0\xa7\x7b\xba\x84\x88\x67\x4e\xe5" > + "\x3c\xcc\x5c\x6a\xe7\x4a\x20\xec\xbe\xcb\xf5\x52\x62\x9f\x37\x80" > + "\x0c\x72\x7b\x83\x66\xa4\xf6\x7f\x95\x97\x1c\x6a\x5c\x7e\xf1\x67" > + "\x37\xb3\x93\x39\x3d\x0b\x55\x35\xd9\xe5\x22\x04\x9f\xf8\xc1\x04" > + "\xce\x13\xa5\xac\xe1\x75\x05\xd1\x2b\x53\xa2\x84\xef\xb1\x18\xf4" > + "\x66\xdd\xea\xe6\x24\x69\x5a\x49\xe0\x7a\xd8\xdf\x1b\xb7\xf1\x6d" > + "\x9b\x50\x2c\xc8\x1c\x1c\xa3\xb4\x37\xfb\x66\x3f\x67\x71\x73\xa9" > + "\xff\x5f\xd9\xa2\x25\x6e\x25\x1b\x26\x54\xbf\x0c\xc6\xdb\xea\x0a" > + "\x52\x6c\x16\x7c\x27\x68\x15\x71\x58\x73\x9d\xe6\xc2\x80\xaa\x97" > + "\x31\x66\xfb\xa6\xfb\xfd\xd0\x9c\x1d\xbe\x81\x48\xf5\x9a\x32\xf1" > + "\x69\x62\x18\x78\xae\x72\x36\xe6\x94\x27\xd1\xff\x18\x4f\x28\x6a" > + "\x16\xbd\x6a\x60\xee\xe5\xf9\x6d\x16\xe4\xb8\xa6\x41\x9b\x23\x7e" > + "\xf7\x9d\xd1\x1d\x03\x15\x66\x3a\xcf\xb6\x2c\x13\x96\x2c\x52\x21" > + "\xe4\x2d\x48\x7a\x8a\x5d\xb2\x88\xed\x98\x61\x79\x8b\x6a\x1e\x5f" > + "\xd0\x8a\x2d\x99\x5a\x2b\x0f\xbc\xef\x53\x8f\x32\xc1\xa2\x99\x26" > + /* p */ > + "\xb9\x36\x3a\xf1\x82\x1f\x60\xd3\x22\x47\xb8\xbc\x2d\x22\x6b\x81" > + "\x7f\xe8\x20\x06\x09\x23\x73\x49\x9a\x59\x8b\x35\x25\xf8\x31\xbc" > + "\x7d\xa8\x1c\x9d\x56\x0d\x1a\xf7\x4b\x4f\x96\xa4\x35\x77\x6a\x89" > + "\xab\x42\x00\x49\x21\x71\xed\x28\x16\x1d\x87\x5a\x10\xa7\x9c\x64" > + "\x94\xd4\x87\x3d\x28\xef\x44\xfe\x4b\xe2\xb4\x15\x8c\x82\xa6\xf3" > + "\x50\x5f\xa8\xe8\xa2\x60\xe7\x00\x86\x78\x05\xd4\x78\x19\xa1\x98" > + "\x62\x4e\x4a\x00\x78\x56\x96\xe6\xcf\xd7\x10\x1b\x74\x5d\xd0\x26" > + "\x61\xdb\x6b\x32\x09\x51\xd8\xa5\xfd\x54\x16\x71\x01\xb3\x39\xe6" > + "\x4e\x69\xb1\xd7\x06\x8f\xd6\x1e\xdc\x72\x25\x26\x74\xc8\x41\x06" > + "\x5c\xd1\x26\x5c\xb0\x2f\xf9\x59\x13\xc1\x2a\x0f\x78\xea\x7b\xf7" > + "\xbd\x59\xa0\x90\x1d\xfc\x33\x5b\x4c\xbf\x05\x9c\x3a\x3f\x69\xa2" > + "\x45\x61\x4e\x10\x6a\xb3\x17\xc5\x68\x30\xfb\x07\x5f\x34\xc6\xfb" > + "\x73\x07\x3c\x70\xf6\xae\xe7\x72\x84\xc3\x18\x81\x8f\xe8\x11\x1f" > + "\x3d\x83\x83\x01\x2a\x14\x73\xbf\x32\x32\x2e\xc9\x4d\xdb\x2a\xca" > + "\xee\x71\xf9\xda\xad\xe8\x82\x0b\x4d\x0c\x1f\xb6\x1d\xef\x00\x67" > + "\x74\x3d\x95\xe0\xb7\xc4\x30\x8a\x24\x87\x12\x47\x27\x70\x0d\x73" > + /* g */ > + "\x02", > + .b_public = > + "\x90\x89\xe4\x82\xd6\x0a\xcf\x1a\xae\xce\x1b\x66\xa7\x19\x71\x18" > + "\x8f\x95\x4b\x5b\x80\x45\x4a\x5a\x43\x99\x4d\x37\xcf\xa3\xa7\x28" > + "\x9c\xc7\x73\xf1\xb2\x17\xf6\x99\xe3\x6b\x56\xcb\x3e\x35\x60\x7d" > + "\x65\xc7\x84\x6b\x3e\x60\xee\xcd\xd2\x70\xe7\xc9\x32\x1c\xf0\xb4" > + "\xf9\x52\xd9\x88\x75\xfd\x40\x2c\xa7\xbe\x19\x1c\x0a\xae\x93\xe1" > + "\x71\xc7\xcd\x4f\x33\x5c\x10\x7d\x39\x56\xfc\x73\x84\xb2\x67\xc3" > + "\x77\x26\x20\x97\x2b\xf8\x13\x43\x93\x9c\x9a\xa4\x08\xc7\x34\x83" > + "\xe6\x98\x61\xe7\x16\x30\x2c\xb1\xdb\x2a\xb2\xcc\xc3\x02\xa5\x3c" > + "\x71\x50\x14\x83\xc7\xbb\xa4\xbe\x98\x1b\xfe\xcb\x43\xe9\x97\x62" > + "\xd6\xf0\x8c\xcb\x1c\xba\x1e\xa8\xa6\xa6\x50\xfc\x85\x7d\x47\xbf" > + "\xf4\x3e\x23\xd3\x5f\xb2\x71\x3e\x40\x94\xaa\x87\x83\x2c\x6c\x8e" > + "\x60\xfd\xdd\xf7\xf4\x76\x03\xd3\x1d\xec\x18\x51\xa3\xf2\x44\x1a" > + "\x3f\xb4\x7c\x18\x0d\x68\x65\x92\x54\x0d\x2d\x81\x16\xf1\x84\x66" > + "\x89\x92\xd0\x1a\x5e\x1f\x42\x46\x5b\xe5\x83\x86\x80\xd9\xcd\x3a" > + "\x5a\x2f\xb9\x59\x9b\xe4\x43\x84\x64\xf3\x09\x1a\x0a\xa2\x64\x0f" > + "\x77\x4e\x8d\x8b\xe6\x88\xd1\xfc\xaf\x8f\xdf\x1d\xbc\x31\xb3\xbd", > + .secret_size = 273, > + .b_secret_size = 529, > + .b_public_size = 256, > + .expected_a_public_size = 256, > + .expected_ss_size = 256, > + .genkey = true, > } > }; > > @@ -840,6 +951,50 @@ static const struct kpp_testvec ecdh_tv_template[] = { > .b_public_size = 64, > .expected_a_public_size = 64, > .expected_ss_size = 32 > + }, { > + .secret = > +#ifdef __LITTLE_ENDIAN > + "\x02\x00" /* type */ > + "\x08\x00" /* len */ > + "\x02\x00" /* curve_id */ > + "\x00\x00", /* key_size */ > +#else > + "\x00\x02" /* type */ > + "\x00\x08" /* len */ > + "\x00\x02" /* curve_id */ > + "\x00\x00", /* key_size */ > +#endif > + .b_secret = > +#ifdef __LITTLE_ENDIAN > + "\x02\x00" /* type */ > + "\x28\x00" /* len */ > + "\x02\x00" /* curve_id */ > + "\x20\x00" /* key_size */ > +#else > + "\x00\x02" /* type */ > + "\x00\x28" /* len */ > + "\x00\x02" /* curve_id */ > + "\x00\x20" /* key_size */ > +#endif > + "\x24\xd1\x21\xeb\xe5\xcf\x2d\x83" > + "\xf6\x62\x1b\x6e\x43\x84\x3a\xa3" > + "\x8b\xe0\x86\xc3\x20\x19\xda\x92" > + "\x50\x53\x03\xe1\xc0\xea\xb8\x82", > + .b_public = > + "\x1a\x7f\xeb\x52\x00\xbd\x3c\x31" > + "\x7d\xb6\x70\xc1\x86\xa6\xc7\xc4" > + "\x3b\xc5\x5f\x6c\x6f\x58\x3c\xf5" > + "\xb6\x63\x82\x77\x33\x24\xa1\x5f" > + "\x6a\xca\x43\x6f\xf7\x7e\xff\x02" > + "\x37\x08\xcc\x40\x5e\x7a\xfd\x6a" > + "\x6a\x02\x6e\x41\x87\x68\x38\x77" > + "\xfa\xa9\x44\x43\x2d\xef\x09\xdf", > + .secret_size = 8, > + .b_secret_size = 40, > + .b_public_size = 64, > + .expected_a_public_size = 64, > + .expected_ss_size = 32, > + .genkey = true, > } > }; Ciao Stephan ^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2017-05-29 13:27 UTC | newest] Thread overview: 14+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2017-05-17 15:26 [RFC PATCH v2 0/4] crypto: (ec)dh - add privkey generation support Tudor Ambarus 2017-05-17 15:26 ` [RFC PATCH v2 1/4] crypto: ecc " Tudor Ambarus 2017-05-28 18:44 ` Stephan Müller 2017-05-29 9:08 ` Tudor Ambarus 2017-05-29 9:23 ` Stephan Müller 2017-05-29 9:47 ` Tudor Ambarus 2017-05-29 9:56 ` Stephan Müller 2017-05-29 13:27 ` Tudor Ambarus 2017-05-17 15:26 ` [RFC PATCH v2 2/4] crypto: ecdh - allow user to provide NULL privkey Tudor Ambarus 2017-05-17 15:26 ` [RFC PATCH v2 3/4] crypto: dh " Tudor Ambarus 2017-05-28 18:50 ` Stephan Müller 2017-05-17 15:26 ` [RFC PATCH v2 4/4] crypto: testmgr - add genkey kpp test Tudor Ambarus 2017-05-26 13:44 ` Tudor Ambarus 2017-05-28 18:57 ` Stephan Müller
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).