diff options
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/ecdh.c | 23 |
1 files changed, 17 insertions, 6 deletions
diff --git a/crypto/ecdh.c b/crypto/ecdh.c index 3aca0933ec44..d2ec33f0e098 100644 --- a/crypto/ecdh.c +++ b/crypto/ecdh.c @@ -89,12 +89,19 @@ static int ecdh_compute_value(struct kpp_request *req) if (!shared_secret) goto free_pubkey; - copied = sg_copy_to_buffer(req->src, 1, public_key, - public_key_sz); - if (copied != public_key_sz) { - ret = -EINVAL; + /* from here on it's invalid parameters */ + ret = -EINVAL; + + /* must have exactly two points to be on the curve */ + if (public_key_sz != req->src_len) + goto free_all; + + copied = sg_copy_to_buffer(req->src, + sg_nents_for_len(req->src, + public_key_sz), + public_key, public_key_sz); + if (copied != public_key_sz) goto free_all; - } ret = crypto_ecdh_shared_secret(ctx->curve_id, ctx->ndigits, ctx->private_key, public_key, @@ -111,7 +118,11 @@ static int ecdh_compute_value(struct kpp_request *req) if (ret < 0) goto free_all; - copied = sg_copy_from_buffer(req->dst, 1, buf, nbytes); + /* might want less than we've got */ + nbytes = min_t(size_t, nbytes, req->dst_len); + copied = sg_copy_from_buffer(req->dst, sg_nents_for_len(req->dst, + nbytes), + buf, nbytes); if (copied != nbytes) ret = -EINVAL; |