^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, ¶ms) < 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, ¶ms) < 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");