Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*  Diffie-Hellman Key Agreement Method [RFC2631]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * Copyright (c) 2016, Intel Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Authors: Salvatore Benedetto <salvatore.benedetto@intel.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <crypto/internal/kpp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <crypto/kpp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <crypto/dh.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/fips.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/mpi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) struct dh_ctx {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) 	MPI p;	/* Value is guaranteed to be set. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) 	MPI q;	/* Value is optional. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 	MPI g;	/* Value is guaranteed to be set. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) 	MPI xa;	/* Value is guaranteed to be set. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) static void dh_clear_ctx(struct dh_ctx *ctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 	mpi_free(ctx->p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 	mpi_free(ctx->q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 	mpi_free(ctx->g);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 	mpi_free(ctx->xa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 	memset(ctx, 0, sizeof(*ctx));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32)  * If base is g we compute the public key
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33)  *	ya = g^xa mod p; [RFC2631 sec 2.1.1]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34)  * else if base if the counterpart public key we compute the shared secret
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35)  *	ZZ = yb^xa mod p; [RFC2631 sec 2.1.1]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) static int _compute_val(const struct dh_ctx *ctx, MPI base, MPI val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	/* val = base^xa mod p */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	return mpi_powm(val, base, ctx->xa, ctx->p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) static inline struct dh_ctx *dh_get_ctx(struct crypto_kpp *tfm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	return kpp_tfm_ctx(tfm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) static int dh_check_params_length(unsigned int p_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	return (p_len < 1536) ? -EINVAL : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) static int dh_set_params(struct dh_ctx *ctx, struct dh *params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	if (dh_check_params_length(params->p_size << 3))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	ctx->p = mpi_read_raw_data(params->p, params->p_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	if (!ctx->p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	if (params->q && params->q_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 		ctx->q = mpi_read_raw_data(params->q, params->q_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 		if (!ctx->q)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	ctx->g = mpi_read_raw_data(params->g, params->g_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	if (!ctx->g)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) static int dh_set_secret(struct crypto_kpp *tfm, const void *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 			 unsigned int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	struct dh_ctx *ctx = dh_get_ctx(tfm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	struct dh params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	/* Free the old MPI key if any */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	dh_clear_ctx(ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	if (crypto_dh_decode_key(buf, len, &params) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 		goto err_clear_ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	if (dh_set_params(ctx, &params) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 		goto err_clear_ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	ctx->xa = mpi_read_raw_data(params.key, params.key_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	if (!ctx->xa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 		goto err_clear_ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) err_clear_ctx:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	dh_clear_ctx(ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)  * SP800-56A public key verification:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)  * * If Q is provided as part of the domain paramenters, a full validation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)  *   according to SP800-56A section 5.6.2.3.1 is performed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)  * * If Q is not provided, a partial validation according to SP800-56A section
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)  *   5.6.2.3.2 is performed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) static int dh_is_pubkey_valid(struct dh_ctx *ctx, MPI y)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	if (unlikely(!ctx->p))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	 * Step 1: Verify that 2 <= y <= p - 2.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	 * The upper limit check is actually y < p instead of y < p - 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	 * as the mpi_sub_ui function is yet missing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	if (mpi_cmp_ui(y, 1) < 1 || mpi_cmp(y, ctx->p) >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	/* Step 2: Verify that 1 = y^q mod p */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	if (ctx->q) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 		MPI val = mpi_alloc(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 		int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 		if (!val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 		ret = mpi_powm(val, y, ctx->q, ctx->p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 		if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 			mpi_free(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 		ret = mpi_cmp_ui(val, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 		mpi_free(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 		if (ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) static int dh_compute_value(struct kpp_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	struct crypto_kpp *tfm = crypto_kpp_reqtfm(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	struct dh_ctx *ctx = dh_get_ctx(tfm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	MPI base, val = mpi_alloc(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	int sign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	if (!val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	if (unlikely(!ctx->xa)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 		ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 		goto err_free_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	if (req->src) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 		base = mpi_read_raw_from_sgl(req->src, req->src_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 		if (!base) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 			ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 			goto err_free_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 		ret = dh_is_pubkey_valid(ctx, base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 			goto err_free_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 		base = ctx->g;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	ret = _compute_val(ctx, base, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 		goto err_free_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	if (fips_enabled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 		/* SP800-56A rev3 5.7.1.1 check: Validation of shared secret */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 		if (req->src) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 			MPI pone;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 			/* z <= 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 			if (mpi_cmp_ui(val, 1) < 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 				ret = -EBADMSG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 				goto err_free_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 			/* z == p - 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 			pone = mpi_alloc(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 			if (!pone) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 				ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 				goto err_free_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 			ret = mpi_sub_ui(pone, ctx->p, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 			if (!ret && !mpi_cmp(pone, val))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 				ret = -EBADMSG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 			mpi_free(pone);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 			if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 				goto err_free_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 		/* SP800-56A rev 3 5.6.2.1.3 key check */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 			if (dh_is_pubkey_valid(ctx, val)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 				ret = -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 				goto err_free_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	ret = mpi_write_to_sgl(val, req->dst, req->dst_len, &sign);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 		goto err_free_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 	if (sign < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 		ret = -EBADMSG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) err_free_base:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	if (req->src)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 		mpi_free(base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) err_free_val:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	mpi_free(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) static unsigned int dh_max_size(struct crypto_kpp *tfm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	struct dh_ctx *ctx = dh_get_ctx(tfm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	return mpi_get_size(ctx->p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) static void dh_exit_tfm(struct crypto_kpp *tfm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	struct dh_ctx *ctx = dh_get_ctx(tfm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 	dh_clear_ctx(ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) static struct kpp_alg dh = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	.set_secret = dh_set_secret,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	.generate_public_key = dh_compute_value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	.compute_shared_secret = dh_compute_value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	.max_size = dh_max_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	.exit = dh_exit_tfm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	.base = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 		.cra_name = "dh",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 		.cra_driver_name = "dh-generic",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 		.cra_priority = 100,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 		.cra_module = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 		.cra_ctxsize = sizeof(struct dh_ctx),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) static int dh_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 	return crypto_register_kpp(&dh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) static void dh_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 	crypto_unregister_kpp(&dh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) subsys_initcall(dh_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) module_exit(dh_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) MODULE_ALIAS_CRYPTO("dh");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) MODULE_DESCRIPTION("DH generic algorithm");