xref: /openbmc/linux/crypto/dh.c (revision 255e48eb)
12874c5fdSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
2802c7f1cSSalvatore Benedetto /*  Diffie-Hellman Key Agreement Method [RFC2631]
3802c7f1cSSalvatore Benedetto  *
4802c7f1cSSalvatore Benedetto  * Copyright (c) 2016, Intel Corporation
5802c7f1cSSalvatore Benedetto  * Authors: Salvatore Benedetto <salvatore.benedetto@intel.com>
6802c7f1cSSalvatore Benedetto  */
7802c7f1cSSalvatore Benedetto 
81e146c39SStephan Müller #include <linux/fips.h>
9802c7f1cSSalvatore Benedetto #include <linux/module.h>
10802c7f1cSSalvatore Benedetto #include <crypto/internal/kpp.h>
11802c7f1cSSalvatore Benedetto #include <crypto/kpp.h>
12802c7f1cSSalvatore Benedetto #include <crypto/dh.h>
131e207964SNicolai Stange #include <crypto/rng.h>
14802c7f1cSSalvatore Benedetto #include <linux/mpi.h>
15802c7f1cSSalvatore Benedetto 
16802c7f1cSSalvatore Benedetto struct dh_ctx {
17e3fe0ae1SStephan Mueller 	MPI p;	/* Value is guaranteed to be set. */
18e3fe0ae1SStephan Mueller 	MPI g;	/* Value is guaranteed to be set. */
19e3fe0ae1SStephan Mueller 	MPI xa;	/* Value is guaranteed to be set. */
20802c7f1cSSalvatore Benedetto };
21802c7f1cSSalvatore Benedetto 
dh_clear_ctx(struct dh_ctx * ctx)2212d41a02SEric Biggers static void dh_clear_ctx(struct dh_ctx *ctx)
23802c7f1cSSalvatore Benedetto {
24802c7f1cSSalvatore Benedetto 	mpi_free(ctx->p);
25802c7f1cSSalvatore Benedetto 	mpi_free(ctx->g);
26802c7f1cSSalvatore Benedetto 	mpi_free(ctx->xa);
2712d41a02SEric Biggers 	memset(ctx, 0, sizeof(*ctx));
28802c7f1cSSalvatore Benedetto }
29802c7f1cSSalvatore Benedetto 
30802c7f1cSSalvatore Benedetto /*
31802c7f1cSSalvatore Benedetto  * If base is g we compute the public key
32802c7f1cSSalvatore Benedetto  *	ya = g^xa mod p; [RFC2631 sec 2.1.1]
33802c7f1cSSalvatore Benedetto  * else if base if the counterpart public key we compute the shared secret
34802c7f1cSSalvatore Benedetto  *	ZZ = yb^xa mod p; [RFC2631 sec 2.1.1]
35802c7f1cSSalvatore Benedetto  */
_compute_val(const struct dh_ctx * ctx,MPI base,MPI val)36802c7f1cSSalvatore Benedetto static int _compute_val(const struct dh_ctx *ctx, MPI base, MPI val)
37802c7f1cSSalvatore Benedetto {
38802c7f1cSSalvatore Benedetto 	/* val = base^xa mod p */
39802c7f1cSSalvatore Benedetto 	return mpi_powm(val, base, ctx->xa, ctx->p);
40802c7f1cSSalvatore Benedetto }
41802c7f1cSSalvatore Benedetto 
dh_get_ctx(struct crypto_kpp * tfm)42802c7f1cSSalvatore Benedetto static inline struct dh_ctx *dh_get_ctx(struct crypto_kpp *tfm)
43802c7f1cSSalvatore Benedetto {
44802c7f1cSSalvatore Benedetto 	return kpp_tfm_ctx(tfm);
45802c7f1cSSalvatore Benedetto }
46802c7f1cSSalvatore Benedetto 
dh_check_params_length(unsigned int p_len)47802c7f1cSSalvatore Benedetto static int dh_check_params_length(unsigned int p_len)
48802c7f1cSSalvatore Benedetto {
491e146c39SStephan Müller 	if (fips_enabled)
501e146c39SStephan Müller 		return (p_len < 2048) ? -EINVAL : 0;
511e146c39SStephan Müller 
52802c7f1cSSalvatore Benedetto 	return (p_len < 1536) ? -EINVAL : 0;
53802c7f1cSSalvatore Benedetto }
54802c7f1cSSalvatore Benedetto 
dh_set_params(struct dh_ctx * ctx,struct dh * params)55802c7f1cSSalvatore Benedetto static int dh_set_params(struct dh_ctx *ctx, struct dh *params)
56802c7f1cSSalvatore Benedetto {
57802c7f1cSSalvatore Benedetto 	if (dh_check_params_length(params->p_size << 3))
58802c7f1cSSalvatore Benedetto 		return -EINVAL;
59802c7f1cSSalvatore Benedetto 
60802c7f1cSSalvatore Benedetto 	ctx->p = mpi_read_raw_data(params->p, params->p_size);
61802c7f1cSSalvatore Benedetto 	if (!ctx->p)
62802c7f1cSSalvatore Benedetto 		return -EINVAL;
63802c7f1cSSalvatore Benedetto 
64802c7f1cSSalvatore Benedetto 	ctx->g = mpi_read_raw_data(params->g, params->g_size);
6512d41a02SEric Biggers 	if (!ctx->g)
66802c7f1cSSalvatore Benedetto 		return -EINVAL;
67802c7f1cSSalvatore Benedetto 
68802c7f1cSSalvatore Benedetto 	return 0;
69802c7f1cSSalvatore Benedetto }
70802c7f1cSSalvatore Benedetto 
dh_set_secret(struct crypto_kpp * tfm,const void * buf,unsigned int len)715527dfb6SEric Biggers static int dh_set_secret(struct crypto_kpp *tfm, const void *buf,
725527dfb6SEric Biggers 			 unsigned int len)
73802c7f1cSSalvatore Benedetto {
74802c7f1cSSalvatore Benedetto 	struct dh_ctx *ctx = dh_get_ctx(tfm);
75802c7f1cSSalvatore Benedetto 	struct dh params;
76802c7f1cSSalvatore Benedetto 
77ee34e264STudor-Dan Ambarus 	/* Free the old MPI key if any */
7812d41a02SEric Biggers 	dh_clear_ctx(ctx);
79ee34e264STudor-Dan Ambarus 
80802c7f1cSSalvatore Benedetto 	if (crypto_dh_decode_key(buf, len, &params) < 0)
8112d41a02SEric Biggers 		goto err_clear_ctx;
82802c7f1cSSalvatore Benedetto 
83802c7f1cSSalvatore Benedetto 	if (dh_set_params(ctx, &params) < 0)
8412d41a02SEric Biggers 		goto err_clear_ctx;
85802c7f1cSSalvatore Benedetto 
86802c7f1cSSalvatore Benedetto 	ctx->xa = mpi_read_raw_data(params.key, params.key_size);
8712d41a02SEric Biggers 	if (!ctx->xa)
8812d41a02SEric Biggers 		goto err_clear_ctx;
89802c7f1cSSalvatore Benedetto 
90802c7f1cSSalvatore Benedetto 	return 0;
9112d41a02SEric Biggers 
9212d41a02SEric Biggers err_clear_ctx:
9312d41a02SEric Biggers 	dh_clear_ctx(ctx);
9412d41a02SEric Biggers 	return -EINVAL;
95802c7f1cSSalvatore Benedetto }
96802c7f1cSSalvatore Benedetto 
97e3fe0ae1SStephan Mueller /*
98e3fe0ae1SStephan Mueller  * SP800-56A public key verification:
99e3fe0ae1SStephan Mueller  *
10035d2bf20SNicolai Stange  * * For the safe-prime groups in FIPS mode, Q can be computed
10135d2bf20SNicolai Stange  *   trivially from P and a full validation according to SP800-56A
10235d2bf20SNicolai Stange  *   section 5.6.2.3.1 is performed.
103e3fe0ae1SStephan Mueller  *
10435d2bf20SNicolai Stange  * * For all other sets of group parameters, only a partial validation
10535d2bf20SNicolai Stange  *   according to SP800-56A section 5.6.2.3.2 is performed.
106e3fe0ae1SStephan Mueller  */
dh_is_pubkey_valid(struct dh_ctx * ctx,MPI y)107e3fe0ae1SStephan Mueller static int dh_is_pubkey_valid(struct dh_ctx *ctx, MPI y)
108e3fe0ae1SStephan Mueller {
109e3fe0ae1SStephan Mueller 	if (unlikely(!ctx->p))
110e3fe0ae1SStephan Mueller 		return -EINVAL;
111e3fe0ae1SStephan Mueller 
112e3fe0ae1SStephan Mueller 	/*
113e3fe0ae1SStephan Mueller 	 * Step 1: Verify that 2 <= y <= p - 2.
114e3fe0ae1SStephan Mueller 	 *
115e3fe0ae1SStephan Mueller 	 * The upper limit check is actually y < p instead of y < p - 1
11635d2bf20SNicolai Stange 	 * in order to save one mpi_sub_ui() invocation here. Note that
11735d2bf20SNicolai Stange 	 * p - 1 is the non-trivial element of the subgroup of order 2 and
11835d2bf20SNicolai Stange 	 * thus, the check on y^q below would fail if y == p - 1.
119e3fe0ae1SStephan Mueller 	 */
120e3fe0ae1SStephan Mueller 	if (mpi_cmp_ui(y, 1) < 1 || mpi_cmp(y, ctx->p) >= 0)
121e3fe0ae1SStephan Mueller 		return -EINVAL;
122e3fe0ae1SStephan Mueller 
12335d2bf20SNicolai Stange 	/*
12435d2bf20SNicolai Stange 	 * Step 2: Verify that 1 = y^q mod p
12535d2bf20SNicolai Stange 	 *
12635d2bf20SNicolai Stange 	 * For the safe-prime groups q = (p - 1)/2.
12735d2bf20SNicolai Stange 	 */
12835d2bf20SNicolai Stange 	if (fips_enabled) {
12935d2bf20SNicolai Stange 		MPI val, q;
130e3fe0ae1SStephan Mueller 		int ret;
131e3fe0ae1SStephan Mueller 
13235d2bf20SNicolai Stange 		val = mpi_alloc(0);
133e3fe0ae1SStephan Mueller 		if (!val)
134e3fe0ae1SStephan Mueller 			return -ENOMEM;
135e3fe0ae1SStephan Mueller 
13635d2bf20SNicolai Stange 		q = mpi_alloc(mpi_get_nlimbs(ctx->p));
13735d2bf20SNicolai Stange 		if (!q) {
13835d2bf20SNicolai Stange 			mpi_free(val);
13935d2bf20SNicolai Stange 			return -ENOMEM;
14035d2bf20SNicolai Stange 		}
141e3fe0ae1SStephan Mueller 
14235d2bf20SNicolai Stange 		/*
14335d2bf20SNicolai Stange 		 * ->p is odd, so no need to explicitly subtract one
14435d2bf20SNicolai Stange 		 * from it before shifting to the right.
14535d2bf20SNicolai Stange 		 */
14635d2bf20SNicolai Stange 		mpi_rshift(q, ctx->p, 1);
14735d2bf20SNicolai Stange 
14835d2bf20SNicolai Stange 		ret = mpi_powm(val, y, q, ctx->p);
14935d2bf20SNicolai Stange 		mpi_free(q);
150e3fe0ae1SStephan Mueller 		if (ret) {
151e3fe0ae1SStephan Mueller 			mpi_free(val);
152e3fe0ae1SStephan Mueller 			return ret;
153e3fe0ae1SStephan Mueller 		}
154e3fe0ae1SStephan Mueller 
155e3fe0ae1SStephan Mueller 		ret = mpi_cmp_ui(val, 1);
156e3fe0ae1SStephan Mueller 
157e3fe0ae1SStephan Mueller 		mpi_free(val);
158e3fe0ae1SStephan Mueller 
159e3fe0ae1SStephan Mueller 		if (ret != 0)
160e3fe0ae1SStephan Mueller 			return -EINVAL;
161e3fe0ae1SStephan Mueller 	}
162e3fe0ae1SStephan Mueller 
163e3fe0ae1SStephan Mueller 	return 0;
164e3fe0ae1SStephan Mueller }
165e3fe0ae1SStephan Mueller 
dh_compute_value(struct kpp_request * req)166802c7f1cSSalvatore Benedetto static int dh_compute_value(struct kpp_request *req)
167802c7f1cSSalvatore Benedetto {
168802c7f1cSSalvatore Benedetto 	struct crypto_kpp *tfm = crypto_kpp_reqtfm(req);
169802c7f1cSSalvatore Benedetto 	struct dh_ctx *ctx = dh_get_ctx(tfm);
170802c7f1cSSalvatore Benedetto 	MPI base, val = mpi_alloc(0);
171802c7f1cSSalvatore Benedetto 	int ret = 0;
172802c7f1cSSalvatore Benedetto 	int sign;
173802c7f1cSSalvatore Benedetto 
174802c7f1cSSalvatore Benedetto 	if (!val)
175802c7f1cSSalvatore Benedetto 		return -ENOMEM;
176802c7f1cSSalvatore Benedetto 
177802c7f1cSSalvatore Benedetto 	if (unlikely(!ctx->xa)) {
178802c7f1cSSalvatore Benedetto 		ret = -EINVAL;
179802c7f1cSSalvatore Benedetto 		goto err_free_val;
180802c7f1cSSalvatore Benedetto 	}
181802c7f1cSSalvatore Benedetto 
182802c7f1cSSalvatore Benedetto 	if (req->src) {
183802c7f1cSSalvatore Benedetto 		base = mpi_read_raw_from_sgl(req->src, req->src_len);
184802c7f1cSSalvatore Benedetto 		if (!base) {
1858edda7d2SMat Martineau 			ret = -EINVAL;
186802c7f1cSSalvatore Benedetto 			goto err_free_val;
187802c7f1cSSalvatore Benedetto 		}
188e3fe0ae1SStephan Mueller 		ret = dh_is_pubkey_valid(ctx, base);
189e3fe0ae1SStephan Mueller 		if (ret)
1903fd8093bSGustavo A. R. Silva 			goto err_free_base;
191802c7f1cSSalvatore Benedetto 	} else {
192802c7f1cSSalvatore Benedetto 		base = ctx->g;
193802c7f1cSSalvatore Benedetto 	}
194802c7f1cSSalvatore Benedetto 
195802c7f1cSSalvatore Benedetto 	ret = _compute_val(ctx, base, val);
196802c7f1cSSalvatore Benedetto 	if (ret)
197802c7f1cSSalvatore Benedetto 		goto err_free_base;
198802c7f1cSSalvatore Benedetto 
1992ed5ba61SStephan Müller 	if (fips_enabled) {
20090fa9ae5SStephan Müller 		/* SP800-56A rev3 5.7.1.1 check: Validation of shared secret */
2012ed5ba61SStephan Müller 		if (req->src) {
20290fa9ae5SStephan Müller 			MPI pone;
20390fa9ae5SStephan Müller 
20490fa9ae5SStephan Müller 			/* z <= 1 */
20590fa9ae5SStephan Müller 			if (mpi_cmp_ui(val, 1) < 1) {
20690fa9ae5SStephan Müller 				ret = -EBADMSG;
20790fa9ae5SStephan Müller 				goto err_free_base;
20890fa9ae5SStephan Müller 			}
20990fa9ae5SStephan Müller 
21090fa9ae5SStephan Müller 			/* z == p - 1 */
21190fa9ae5SStephan Müller 			pone = mpi_alloc(0);
21290fa9ae5SStephan Müller 
21390fa9ae5SStephan Müller 			if (!pone) {
21490fa9ae5SStephan Müller 				ret = -ENOMEM;
21590fa9ae5SStephan Müller 				goto err_free_base;
21690fa9ae5SStephan Müller 			}
21790fa9ae5SStephan Müller 
21890fa9ae5SStephan Müller 			ret = mpi_sub_ui(pone, ctx->p, 1);
21990fa9ae5SStephan Müller 			if (!ret && !mpi_cmp(pone, val))
22090fa9ae5SStephan Müller 				ret = -EBADMSG;
22190fa9ae5SStephan Müller 
22290fa9ae5SStephan Müller 			mpi_free(pone);
22390fa9ae5SStephan Müller 
22490fa9ae5SStephan Müller 			if (ret)
22590fa9ae5SStephan Müller 				goto err_free_base;
2262ed5ba61SStephan Müller 
2272ed5ba61SStephan Müller 		/* SP800-56A rev 3 5.6.2.1.3 key check */
2282ed5ba61SStephan Müller 		} else {
2292ed5ba61SStephan Müller 			if (dh_is_pubkey_valid(ctx, val)) {
2302ed5ba61SStephan Müller 				ret = -EAGAIN;
2312ed5ba61SStephan Müller 				goto err_free_val;
2322ed5ba61SStephan Müller 			}
2332ed5ba61SStephan Müller 		}
23490fa9ae5SStephan Müller 	}
23590fa9ae5SStephan Müller 
2369b45b7bbSHerbert Xu 	ret = mpi_write_to_sgl(val, req->dst, req->dst_len, &sign);
237802c7f1cSSalvatore Benedetto 	if (ret)
238802c7f1cSSalvatore Benedetto 		goto err_free_base;
239802c7f1cSSalvatore Benedetto 
240802c7f1cSSalvatore Benedetto 	if (sign < 0)
241802c7f1cSSalvatore Benedetto 		ret = -EBADMSG;
242802c7f1cSSalvatore Benedetto err_free_base:
243802c7f1cSSalvatore Benedetto 	if (req->src)
244802c7f1cSSalvatore Benedetto 		mpi_free(base);
245802c7f1cSSalvatore Benedetto err_free_val:
246802c7f1cSSalvatore Benedetto 	mpi_free(val);
247802c7f1cSSalvatore Benedetto 	return ret;
248802c7f1cSSalvatore Benedetto }
249802c7f1cSSalvatore Benedetto 
dh_max_size(struct crypto_kpp * tfm)2507f691050STudor-Dan Ambarus static unsigned int dh_max_size(struct crypto_kpp *tfm)
251802c7f1cSSalvatore Benedetto {
252802c7f1cSSalvatore Benedetto 	struct dh_ctx *ctx = dh_get_ctx(tfm);
253802c7f1cSSalvatore Benedetto 
254802c7f1cSSalvatore Benedetto 	return mpi_get_size(ctx->p);
255802c7f1cSSalvatore Benedetto }
256802c7f1cSSalvatore Benedetto 
dh_exit_tfm(struct crypto_kpp * tfm)257802c7f1cSSalvatore Benedetto static void dh_exit_tfm(struct crypto_kpp *tfm)
258802c7f1cSSalvatore Benedetto {
259802c7f1cSSalvatore Benedetto 	struct dh_ctx *ctx = dh_get_ctx(tfm);
260802c7f1cSSalvatore Benedetto 
26112d41a02SEric Biggers 	dh_clear_ctx(ctx);
262802c7f1cSSalvatore Benedetto }
263802c7f1cSSalvatore Benedetto 
264802c7f1cSSalvatore Benedetto static struct kpp_alg dh = {
265802c7f1cSSalvatore Benedetto 	.set_secret = dh_set_secret,
266802c7f1cSSalvatore Benedetto 	.generate_public_key = dh_compute_value,
267802c7f1cSSalvatore Benedetto 	.compute_shared_secret = dh_compute_value,
268802c7f1cSSalvatore Benedetto 	.max_size = dh_max_size,
269802c7f1cSSalvatore Benedetto 	.exit = dh_exit_tfm,
270802c7f1cSSalvatore Benedetto 	.base = {
271802c7f1cSSalvatore Benedetto 		.cra_name = "dh",
272802c7f1cSSalvatore Benedetto 		.cra_driver_name = "dh-generic",
273802c7f1cSSalvatore Benedetto 		.cra_priority = 100,
274802c7f1cSSalvatore Benedetto 		.cra_module = THIS_MODULE,
275802c7f1cSSalvatore Benedetto 		.cra_ctxsize = sizeof(struct dh_ctx),
276802c7f1cSSalvatore Benedetto 	},
277802c7f1cSSalvatore Benedetto };
278802c7f1cSSalvatore Benedetto 
279d902981fSNicolai Stange 
280d902981fSNicolai Stange struct dh_safe_prime {
281d902981fSNicolai Stange 	unsigned int max_strength;
282d902981fSNicolai Stange 	unsigned int p_size;
283d902981fSNicolai Stange 	const char *p;
284d902981fSNicolai Stange };
285d902981fSNicolai Stange 
286d902981fSNicolai Stange static const char safe_prime_g[]  = { 2 };
287d902981fSNicolai Stange 
288d902981fSNicolai Stange struct dh_safe_prime_instance_ctx {
289d902981fSNicolai Stange 	struct crypto_kpp_spawn dh_spawn;
290d902981fSNicolai Stange 	const struct dh_safe_prime *safe_prime;
291d902981fSNicolai Stange };
292d902981fSNicolai Stange 
293d902981fSNicolai Stange struct dh_safe_prime_tfm_ctx {
294d902981fSNicolai Stange 	struct crypto_kpp *dh_tfm;
295d902981fSNicolai Stange };
296d902981fSNicolai Stange 
dh_safe_prime_free_instance(struct kpp_instance * inst)297d902981fSNicolai Stange static void dh_safe_prime_free_instance(struct kpp_instance *inst)
298d902981fSNicolai Stange {
299d902981fSNicolai Stange 	struct dh_safe_prime_instance_ctx *ctx = kpp_instance_ctx(inst);
300d902981fSNicolai Stange 
301d902981fSNicolai Stange 	crypto_drop_kpp(&ctx->dh_spawn);
302d902981fSNicolai Stange 	kfree(inst);
303d902981fSNicolai Stange }
304d902981fSNicolai Stange 
dh_safe_prime_instance_ctx(struct crypto_kpp * tfm)305d902981fSNicolai Stange static inline struct dh_safe_prime_instance_ctx *dh_safe_prime_instance_ctx(
306d902981fSNicolai Stange 	struct crypto_kpp *tfm)
307d902981fSNicolai Stange {
308d902981fSNicolai Stange 	return kpp_instance_ctx(kpp_alg_instance(tfm));
309d902981fSNicolai Stange }
310d902981fSNicolai Stange 
dh_safe_prime_init_tfm(struct crypto_kpp * tfm)311d902981fSNicolai Stange static int dh_safe_prime_init_tfm(struct crypto_kpp *tfm)
312d902981fSNicolai Stange {
313d902981fSNicolai Stange 	struct dh_safe_prime_instance_ctx *inst_ctx =
314d902981fSNicolai Stange 		dh_safe_prime_instance_ctx(tfm);
315d902981fSNicolai Stange 	struct dh_safe_prime_tfm_ctx *tfm_ctx = kpp_tfm_ctx(tfm);
316d902981fSNicolai Stange 
317d902981fSNicolai Stange 	tfm_ctx->dh_tfm = crypto_spawn_kpp(&inst_ctx->dh_spawn);
318d902981fSNicolai Stange 	if (IS_ERR(tfm_ctx->dh_tfm))
319d902981fSNicolai Stange 		return PTR_ERR(tfm_ctx->dh_tfm);
320d902981fSNicolai Stange 
321cb99fc0dSHerbert Xu 	kpp_set_reqsize(tfm, sizeof(struct kpp_request) +
322cb99fc0dSHerbert Xu 			     crypto_kpp_reqsize(tfm_ctx->dh_tfm));
323cb99fc0dSHerbert Xu 
324d902981fSNicolai Stange 	return 0;
325d902981fSNicolai Stange }
326d902981fSNicolai Stange 
dh_safe_prime_exit_tfm(struct crypto_kpp * tfm)327d902981fSNicolai Stange static void dh_safe_prime_exit_tfm(struct crypto_kpp *tfm)
328d902981fSNicolai Stange {
329d902981fSNicolai Stange 	struct dh_safe_prime_tfm_ctx *tfm_ctx = kpp_tfm_ctx(tfm);
330d902981fSNicolai Stange 
331d902981fSNicolai Stange 	crypto_free_kpp(tfm_ctx->dh_tfm);
332d902981fSNicolai Stange }
333d902981fSNicolai Stange 
__add_u64_to_be(__be64 * dst,unsigned int n,u64 val)3341e207964SNicolai Stange static u64 __add_u64_to_be(__be64 *dst, unsigned int n, u64 val)
3351e207964SNicolai Stange {
3361e207964SNicolai Stange 	unsigned int i;
3371e207964SNicolai Stange 
3381e207964SNicolai Stange 	for (i = n; val && i > 0; --i) {
3391e207964SNicolai Stange 		u64 tmp = be64_to_cpu(dst[i - 1]);
3401e207964SNicolai Stange 
3411e207964SNicolai Stange 		tmp += val;
3421e207964SNicolai Stange 		val = tmp >= val ? 0 : 1;
3431e207964SNicolai Stange 		dst[i - 1] = cpu_to_be64(tmp);
3441e207964SNicolai Stange 	}
3451e207964SNicolai Stange 
3461e207964SNicolai Stange 	return val;
3471e207964SNicolai Stange }
3481e207964SNicolai Stange 
dh_safe_prime_gen_privkey(const struct dh_safe_prime * safe_prime,unsigned int * key_size)3491e207964SNicolai Stange static void *dh_safe_prime_gen_privkey(const struct dh_safe_prime *safe_prime,
3501e207964SNicolai Stange 				       unsigned int *key_size)
3511e207964SNicolai Stange {
3521e207964SNicolai Stange 	unsigned int n, oversampling_size;
3531e207964SNicolai Stange 	__be64 *key;
3541e207964SNicolai Stange 	int err;
3551e207964SNicolai Stange 	u64 h, o;
3561e207964SNicolai Stange 
3571e207964SNicolai Stange 	/*
3581e207964SNicolai Stange 	 * Generate a private key following NIST SP800-56Ar3,
3591e207964SNicolai Stange 	 * sec. 5.6.1.1.1 and 5.6.1.1.3 resp..
3601e207964SNicolai Stange 	 *
3611e207964SNicolai Stange 	 * 5.6.1.1.1: choose key length N such that
3621e207964SNicolai Stange 	 * 2 * ->max_strength <= N <= log2(q) + 1 = ->p_size * 8 - 1
3631e207964SNicolai Stange 	 * with q = (p - 1) / 2 for the safe-prime groups.
3641e207964SNicolai Stange 	 * Choose the lower bound's next power of two for N in order to
3651e207964SNicolai Stange 	 * avoid excessively large private keys while still
3661e207964SNicolai Stange 	 * maintaining some extra reserve beyond the bare minimum in
3671e207964SNicolai Stange 	 * most cases. Note that for each entry in safe_prime_groups[],
3681e207964SNicolai Stange 	 * the following holds for such N:
3691e207964SNicolai Stange 	 * - N >= 256, in particular it is a multiple of 2^6 = 64
3701e207964SNicolai Stange 	 *   bits and
3711e207964SNicolai Stange 	 * - N < log2(q) + 1, i.e. N respects the upper bound.
3721e207964SNicolai Stange 	 */
3731e207964SNicolai Stange 	n = roundup_pow_of_two(2 * safe_prime->max_strength);
3741e207964SNicolai Stange 	WARN_ON_ONCE(n & ((1u << 6) - 1));
3751e207964SNicolai Stange 	n >>= 6; /* Convert N into units of u64. */
3761e207964SNicolai Stange 
3771e207964SNicolai Stange 	/*
3781e207964SNicolai Stange 	 * Reserve one extra u64 to hold the extra random bits
3791e207964SNicolai Stange 	 * required as per 5.6.1.1.3.
3801e207964SNicolai Stange 	 */
3811e207964SNicolai Stange 	oversampling_size = (n + 1) * sizeof(__be64);
3821e207964SNicolai Stange 	key = kmalloc(oversampling_size, GFP_KERNEL);
3831e207964SNicolai Stange 	if (!key)
3841e207964SNicolai Stange 		return ERR_PTR(-ENOMEM);
3851e207964SNicolai Stange 
3861e207964SNicolai Stange 	/*
3871e207964SNicolai Stange 	 * 5.6.1.1.3, step 3 (and implicitly step 4): obtain N + 64
3881e207964SNicolai Stange 	 * random bits and interpret them as a big endian integer.
3891e207964SNicolai Stange 	 */
3901e207964SNicolai Stange 	err = -EFAULT;
3911e207964SNicolai Stange 	if (crypto_get_default_rng())
3921e207964SNicolai Stange 		goto out_err;
3931e207964SNicolai Stange 
3941e207964SNicolai Stange 	err = crypto_rng_get_bytes(crypto_default_rng, (u8 *)key,
3951e207964SNicolai Stange 				   oversampling_size);
3961e207964SNicolai Stange 	crypto_put_default_rng();
3971e207964SNicolai Stange 	if (err)
3981e207964SNicolai Stange 		goto out_err;
3991e207964SNicolai Stange 
4001e207964SNicolai Stange 	/*
4011e207964SNicolai Stange 	 * 5.6.1.1.3, step 5 is implicit: 2^N < q and thus,
4021e207964SNicolai Stange 	 * M = min(2^N, q) = 2^N.
4031e207964SNicolai Stange 	 *
4041e207964SNicolai Stange 	 * For step 6, calculate
4051e207964SNicolai Stange 	 * key = (key[] mod (M - 1)) + 1 = (key[] mod (2^N - 1)) + 1.
4061e207964SNicolai Stange 	 *
4071e207964SNicolai Stange 	 * In order to avoid expensive divisions, note that
4081e207964SNicolai Stange 	 * 2^N mod (2^N - 1) = 1 and thus, for any integer h,
4091e207964SNicolai Stange 	 * 2^N * h mod (2^N - 1) = h mod (2^N - 1) always holds.
4101e207964SNicolai Stange 	 * The big endian integer key[] composed of n + 1 64bit words
4111e207964SNicolai Stange 	 * may be written as key[] = h * 2^N + l, with h = key[0]
4121e207964SNicolai Stange 	 * representing the 64 most significant bits and l
4131e207964SNicolai Stange 	 * corresponding to the remaining 2^N bits. With the remark
4141e207964SNicolai Stange 	 * from above,
4151e207964SNicolai Stange 	 * h * 2^N + l mod (2^N - 1) = l + h mod (2^N - 1).
4161e207964SNicolai Stange 	 * As both, l and h are less than 2^N, their sum after
4171e207964SNicolai Stange 	 * this first reduction is guaranteed to be <= 2^(N + 1) - 2.
4181e207964SNicolai Stange 	 * Or equivalently, that their sum can again be written as
4191e207964SNicolai Stange 	 * h' * 2^N + l' with h' now either zero or one and if one,
4201e207964SNicolai Stange 	 * then l' <= 2^N - 2. Thus, all bits at positions >= N will
4211e207964SNicolai Stange 	 * be zero after a second reduction:
4221e207964SNicolai Stange 	 * h' * 2^N + l' mod (2^N - 1) = l' + h' mod (2^N - 1).
4231e207964SNicolai Stange 	 * At this point, it is still possible that
4241e207964SNicolai Stange 	 * l' + h' = 2^N - 1, i.e. that l' + h' mod (2^N - 1)
4251e207964SNicolai Stange 	 * is zero. This condition will be detected below by means of
4261e207964SNicolai Stange 	 * the final increment overflowing in this case.
4271e207964SNicolai Stange 	 */
4281e207964SNicolai Stange 	h = be64_to_cpu(key[0]);
4291e207964SNicolai Stange 	h = __add_u64_to_be(key + 1, n, h);
4301e207964SNicolai Stange 	h = __add_u64_to_be(key + 1, n, h);
4311e207964SNicolai Stange 	WARN_ON_ONCE(h);
4321e207964SNicolai Stange 
4331e207964SNicolai Stange 	/* Increment to obtain the final result. */
4341e207964SNicolai Stange 	o = __add_u64_to_be(key + 1, n, 1);
4351e207964SNicolai Stange 	/*
4361e207964SNicolai Stange 	 * The overflow bit o from the increment is either zero or
4371e207964SNicolai Stange 	 * one. If zero, key[1:n] holds the final result in big-endian
4381e207964SNicolai Stange 	 * order. If one, key[1:n] is zero now, but needs to be set to
4391e207964SNicolai Stange 	 * one, c.f. above.
4401e207964SNicolai Stange 	 */
4411e207964SNicolai Stange 	if (o)
4421e207964SNicolai Stange 		key[n] = cpu_to_be64(1);
4431e207964SNicolai Stange 
4441e207964SNicolai Stange 	/* n is in units of u64, convert to bytes. */
4451e207964SNicolai Stange 	*key_size = n << 3;
4461e207964SNicolai Stange 	/* Strip the leading extra __be64, which is (virtually) zero by now. */
4471e207964SNicolai Stange 	memmove(key, &key[1], *key_size);
4481e207964SNicolai Stange 
4491e207964SNicolai Stange 	return key;
4501e207964SNicolai Stange 
4511e207964SNicolai Stange out_err:
4521e207964SNicolai Stange 	kfree_sensitive(key);
4531e207964SNicolai Stange 	return ERR_PTR(err);
4541e207964SNicolai Stange }
4551e207964SNicolai Stange 
dh_safe_prime_set_secret(struct crypto_kpp * tfm,const void * buffer,unsigned int len)456d902981fSNicolai Stange static int dh_safe_prime_set_secret(struct crypto_kpp *tfm, const void *buffer,
457d902981fSNicolai Stange 				    unsigned int len)
458d902981fSNicolai Stange {
459d902981fSNicolai Stange 	struct dh_safe_prime_instance_ctx *inst_ctx =
460d902981fSNicolai Stange 		dh_safe_prime_instance_ctx(tfm);
461d902981fSNicolai Stange 	struct dh_safe_prime_tfm_ctx *tfm_ctx = kpp_tfm_ctx(tfm);
462c8e8236cSNicolai Stange 	struct dh params = {};
4631e207964SNicolai Stange 	void *buf = NULL, *key = NULL;
464d902981fSNicolai Stange 	unsigned int buf_size;
465d902981fSNicolai Stange 	int err;
466d902981fSNicolai Stange 
467c8e8236cSNicolai Stange 	if (buffer) {
468d902981fSNicolai Stange 		err = __crypto_dh_decode_key(buffer, len, &params);
469d902981fSNicolai Stange 		if (err)
470d902981fSNicolai Stange 			return err;
471d902981fSNicolai Stange 		if (params.p_size || params.g_size)
472d902981fSNicolai Stange 			return -EINVAL;
473c8e8236cSNicolai Stange 	}
474d902981fSNicolai Stange 
475d902981fSNicolai Stange 	params.p = inst_ctx->safe_prime->p;
476d902981fSNicolai Stange 	params.p_size = inst_ctx->safe_prime->p_size;
477d902981fSNicolai Stange 	params.g = safe_prime_g;
478d902981fSNicolai Stange 	params.g_size = sizeof(safe_prime_g);
479d902981fSNicolai Stange 
4801e207964SNicolai Stange 	if (!params.key_size) {
4811e207964SNicolai Stange 		key = dh_safe_prime_gen_privkey(inst_ctx->safe_prime,
4821e207964SNicolai Stange 						&params.key_size);
4831e207964SNicolai Stange 		if (IS_ERR(key))
4841e207964SNicolai Stange 			return PTR_ERR(key);
4851e207964SNicolai Stange 		params.key = key;
4861e207964SNicolai Stange 	}
4871e207964SNicolai Stange 
488d902981fSNicolai Stange 	buf_size = crypto_dh_key_len(&params);
489d902981fSNicolai Stange 	buf = kmalloc(buf_size, GFP_KERNEL);
4901e207964SNicolai Stange 	if (!buf) {
4911e207964SNicolai Stange 		err = -ENOMEM;
4921e207964SNicolai Stange 		goto out;
4931e207964SNicolai Stange 	}
494d902981fSNicolai Stange 
495d902981fSNicolai Stange 	err = crypto_dh_encode_key(buf, buf_size, &params);
496d902981fSNicolai Stange 	if (err)
497d902981fSNicolai Stange 		goto out;
498d902981fSNicolai Stange 
499d902981fSNicolai Stange 	err = crypto_kpp_set_secret(tfm_ctx->dh_tfm, buf, buf_size);
500d902981fSNicolai Stange out:
501d902981fSNicolai Stange 	kfree_sensitive(buf);
5021e207964SNicolai Stange 	kfree_sensitive(key);
503d902981fSNicolai Stange 	return err;
504d902981fSNicolai Stange }
505d902981fSNicolai Stange 
dh_safe_prime_complete_req(void * data,int err)506*255e48ebSHerbert Xu static void dh_safe_prime_complete_req(void *data, int err)
507d902981fSNicolai Stange {
508*255e48ebSHerbert Xu 	struct kpp_request *req = data;
509d902981fSNicolai Stange 
510d902981fSNicolai Stange 	kpp_request_complete(req, err);
511d902981fSNicolai Stange }
512d902981fSNicolai Stange 
dh_safe_prime_prepare_dh_req(struct kpp_request * req)513d902981fSNicolai Stange static struct kpp_request *dh_safe_prime_prepare_dh_req(struct kpp_request *req)
514d902981fSNicolai Stange {
515d902981fSNicolai Stange 	struct dh_safe_prime_tfm_ctx *tfm_ctx =
516d902981fSNicolai Stange 		kpp_tfm_ctx(crypto_kpp_reqtfm(req));
517d902981fSNicolai Stange 	struct kpp_request *dh_req = kpp_request_ctx(req);
518d902981fSNicolai Stange 
519d902981fSNicolai Stange 	kpp_request_set_tfm(dh_req, tfm_ctx->dh_tfm);
520d902981fSNicolai Stange 	kpp_request_set_callback(dh_req, req->base.flags,
521d902981fSNicolai Stange 				 dh_safe_prime_complete_req, req);
522d902981fSNicolai Stange 
523d902981fSNicolai Stange 	kpp_request_set_input(dh_req, req->src, req->src_len);
524d902981fSNicolai Stange 	kpp_request_set_output(dh_req, req->dst, req->dst_len);
525d902981fSNicolai Stange 
526d902981fSNicolai Stange 	return dh_req;
527d902981fSNicolai Stange }
528d902981fSNicolai Stange 
dh_safe_prime_generate_public_key(struct kpp_request * req)529d902981fSNicolai Stange static int dh_safe_prime_generate_public_key(struct kpp_request *req)
530d902981fSNicolai Stange {
531d902981fSNicolai Stange 	struct kpp_request *dh_req = dh_safe_prime_prepare_dh_req(req);
532d902981fSNicolai Stange 
533d902981fSNicolai Stange 	return crypto_kpp_generate_public_key(dh_req);
534d902981fSNicolai Stange }
535d902981fSNicolai Stange 
dh_safe_prime_compute_shared_secret(struct kpp_request * req)536d902981fSNicolai Stange static int dh_safe_prime_compute_shared_secret(struct kpp_request *req)
537d902981fSNicolai Stange {
538d902981fSNicolai Stange 	struct kpp_request *dh_req = dh_safe_prime_prepare_dh_req(req);
539d902981fSNicolai Stange 
540d902981fSNicolai Stange 	return crypto_kpp_compute_shared_secret(dh_req);
541d902981fSNicolai Stange }
542d902981fSNicolai Stange 
dh_safe_prime_max_size(struct crypto_kpp * tfm)543d902981fSNicolai Stange static unsigned int dh_safe_prime_max_size(struct crypto_kpp *tfm)
544d902981fSNicolai Stange {
545d902981fSNicolai Stange 	struct dh_safe_prime_tfm_ctx *tfm_ctx = kpp_tfm_ctx(tfm);
546d902981fSNicolai Stange 
547d902981fSNicolai Stange 	return crypto_kpp_maxsize(tfm_ctx->dh_tfm);
548d902981fSNicolai Stange }
549d902981fSNicolai Stange 
__dh_safe_prime_create(struct crypto_template * tmpl,struct rtattr ** tb,const struct dh_safe_prime * safe_prime)550d902981fSNicolai Stange static int __maybe_unused __dh_safe_prime_create(
551d902981fSNicolai Stange 	struct crypto_template *tmpl, struct rtattr **tb,
552d902981fSNicolai Stange 	const struct dh_safe_prime *safe_prime)
553d902981fSNicolai Stange {
554d902981fSNicolai Stange 	struct kpp_instance *inst;
555d902981fSNicolai Stange 	struct dh_safe_prime_instance_ctx *ctx;
556d902981fSNicolai Stange 	const char *dh_name;
557d902981fSNicolai Stange 	struct kpp_alg *dh_alg;
558d902981fSNicolai Stange 	u32 mask;
559d902981fSNicolai Stange 	int err;
560d902981fSNicolai Stange 
561d902981fSNicolai Stange 	err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_KPP, &mask);
562d902981fSNicolai Stange 	if (err)
563d902981fSNicolai Stange 		return err;
564d902981fSNicolai Stange 
565d902981fSNicolai Stange 	dh_name = crypto_attr_alg_name(tb[1]);
566d902981fSNicolai Stange 	if (IS_ERR(dh_name))
567d902981fSNicolai Stange 		return PTR_ERR(dh_name);
568d902981fSNicolai Stange 
569d902981fSNicolai Stange 	inst = kzalloc(sizeof(*inst) + sizeof(*ctx), GFP_KERNEL);
570d902981fSNicolai Stange 	if (!inst)
571d902981fSNicolai Stange 		return -ENOMEM;
572d902981fSNicolai Stange 
573d902981fSNicolai Stange 	ctx = kpp_instance_ctx(inst);
574d902981fSNicolai Stange 
575d902981fSNicolai Stange 	err = crypto_grab_kpp(&ctx->dh_spawn, kpp_crypto_instance(inst),
576d902981fSNicolai Stange 			      dh_name, 0, mask);
577d902981fSNicolai Stange 	if (err)
578d902981fSNicolai Stange 		goto err_free_inst;
579d902981fSNicolai Stange 
580d902981fSNicolai Stange 	err = -EINVAL;
581d902981fSNicolai Stange 	dh_alg = crypto_spawn_kpp_alg(&ctx->dh_spawn);
582d902981fSNicolai Stange 	if (strcmp(dh_alg->base.cra_name, "dh"))
583d902981fSNicolai Stange 		goto err_free_inst;
584d902981fSNicolai Stange 
585d902981fSNicolai Stange 	ctx->safe_prime = safe_prime;
586d902981fSNicolai Stange 
587d902981fSNicolai Stange 	err = crypto_inst_setname(kpp_crypto_instance(inst),
588d902981fSNicolai Stange 				  tmpl->name, &dh_alg->base);
589d902981fSNicolai Stange 	if (err)
590d902981fSNicolai Stange 		goto err_free_inst;
591d902981fSNicolai Stange 
592d902981fSNicolai Stange 	inst->alg.set_secret = dh_safe_prime_set_secret;
593d902981fSNicolai Stange 	inst->alg.generate_public_key = dh_safe_prime_generate_public_key;
594d902981fSNicolai Stange 	inst->alg.compute_shared_secret = dh_safe_prime_compute_shared_secret;
595d902981fSNicolai Stange 	inst->alg.max_size = dh_safe_prime_max_size;
596d902981fSNicolai Stange 	inst->alg.init = dh_safe_prime_init_tfm;
597d902981fSNicolai Stange 	inst->alg.exit = dh_safe_prime_exit_tfm;
598d902981fSNicolai Stange 	inst->alg.base.cra_priority = dh_alg->base.cra_priority;
599d902981fSNicolai Stange 	inst->alg.base.cra_module = THIS_MODULE;
600d902981fSNicolai Stange 	inst->alg.base.cra_ctxsize = sizeof(struct dh_safe_prime_tfm_ctx);
601d902981fSNicolai Stange 
602d902981fSNicolai Stange 	inst->free = dh_safe_prime_free_instance;
603d902981fSNicolai Stange 
604d902981fSNicolai Stange 	err = kpp_register_instance(tmpl, inst);
605d902981fSNicolai Stange 	if (err)
606d902981fSNicolai Stange 		goto err_free_inst;
607d902981fSNicolai Stange 
608d902981fSNicolai Stange 	return 0;
609d902981fSNicolai Stange 
610d902981fSNicolai Stange err_free_inst:
611d902981fSNicolai Stange 	dh_safe_prime_free_instance(inst);
612d902981fSNicolai Stange 
613d902981fSNicolai Stange 	return err;
614d902981fSNicolai Stange }
615d902981fSNicolai Stange 
6167dce5981SNicolai Stange #ifdef CONFIG_CRYPTO_DH_RFC7919_GROUPS
6177dce5981SNicolai Stange 
6187dce5981SNicolai Stange static const struct dh_safe_prime ffdhe2048_prime = {
6197dce5981SNicolai Stange 	.max_strength = 112,
6207dce5981SNicolai Stange 	.p_size = 256,
6217dce5981SNicolai Stange 	.p =
6227dce5981SNicolai Stange 	"\xff\xff\xff\xff\xff\xff\xff\xff\xad\xf8\x54\x58\xa2\xbb\x4a\x9a"
6237dce5981SNicolai Stange 	"\xaf\xdc\x56\x20\x27\x3d\x3c\xf1\xd8\xb9\xc5\x83\xce\x2d\x36\x95"
6247dce5981SNicolai Stange 	"\xa9\xe1\x36\x41\x14\x64\x33\xfb\xcc\x93\x9d\xce\x24\x9b\x3e\xf9"
6257dce5981SNicolai Stange 	"\x7d\x2f\xe3\x63\x63\x0c\x75\xd8\xf6\x81\xb2\x02\xae\xc4\x61\x7a"
6267dce5981SNicolai Stange 	"\xd3\xdf\x1e\xd5\xd5\xfd\x65\x61\x24\x33\xf5\x1f\x5f\x06\x6e\xd0"
6277dce5981SNicolai Stange 	"\x85\x63\x65\x55\x3d\xed\x1a\xf3\xb5\x57\x13\x5e\x7f\x57\xc9\x35"
6287dce5981SNicolai Stange 	"\x98\x4f\x0c\x70\xe0\xe6\x8b\x77\xe2\xa6\x89\xda\xf3\xef\xe8\x72"
6297dce5981SNicolai Stange 	"\x1d\xf1\x58\xa1\x36\xad\xe7\x35\x30\xac\xca\x4f\x48\x3a\x79\x7a"
6307dce5981SNicolai Stange 	"\xbc\x0a\xb1\x82\xb3\x24\xfb\x61\xd1\x08\xa9\x4b\xb2\xc8\xe3\xfb"
6317dce5981SNicolai Stange 	"\xb9\x6a\xda\xb7\x60\xd7\xf4\x68\x1d\x4f\x42\xa3\xde\x39\x4d\xf4"
6327dce5981SNicolai Stange 	"\xae\x56\xed\xe7\x63\x72\xbb\x19\x0b\x07\xa7\xc8\xee\x0a\x6d\x70"
6337dce5981SNicolai Stange 	"\x9e\x02\xfc\xe1\xcd\xf7\xe2\xec\xc0\x34\x04\xcd\x28\x34\x2f\x61"
6347dce5981SNicolai Stange 	"\x91\x72\xfe\x9c\xe9\x85\x83\xff\x8e\x4f\x12\x32\xee\xf2\x81\x83"
6357dce5981SNicolai Stange 	"\xc3\xfe\x3b\x1b\x4c\x6f\xad\x73\x3b\xb5\xfc\xbc\x2e\xc2\x20\x05"
6367dce5981SNicolai Stange 	"\xc5\x8e\xf1\x83\x7d\x16\x83\xb2\xc6\xf3\x4a\x26\xc1\xb2\xef\xfa"
6377dce5981SNicolai Stange 	"\x88\x6b\x42\x38\x61\x28\x5c\x97\xff\xff\xff\xff\xff\xff\xff\xff",
6387dce5981SNicolai Stange };
6397dce5981SNicolai Stange 
6407dce5981SNicolai Stange static const struct dh_safe_prime ffdhe3072_prime = {
6417dce5981SNicolai Stange 	.max_strength = 128,
6427dce5981SNicolai Stange 	.p_size = 384,
6437dce5981SNicolai Stange 	.p =
6447dce5981SNicolai Stange 	"\xff\xff\xff\xff\xff\xff\xff\xff\xad\xf8\x54\x58\xa2\xbb\x4a\x9a"
6457dce5981SNicolai Stange 	"\xaf\xdc\x56\x20\x27\x3d\x3c\xf1\xd8\xb9\xc5\x83\xce\x2d\x36\x95"
6467dce5981SNicolai Stange 	"\xa9\xe1\x36\x41\x14\x64\x33\xfb\xcc\x93\x9d\xce\x24\x9b\x3e\xf9"
6477dce5981SNicolai Stange 	"\x7d\x2f\xe3\x63\x63\x0c\x75\xd8\xf6\x81\xb2\x02\xae\xc4\x61\x7a"
6487dce5981SNicolai Stange 	"\xd3\xdf\x1e\xd5\xd5\xfd\x65\x61\x24\x33\xf5\x1f\x5f\x06\x6e\xd0"
6497dce5981SNicolai Stange 	"\x85\x63\x65\x55\x3d\xed\x1a\xf3\xb5\x57\x13\x5e\x7f\x57\xc9\x35"
6507dce5981SNicolai Stange 	"\x98\x4f\x0c\x70\xe0\xe6\x8b\x77\xe2\xa6\x89\xda\xf3\xef\xe8\x72"
6517dce5981SNicolai Stange 	"\x1d\xf1\x58\xa1\x36\xad\xe7\x35\x30\xac\xca\x4f\x48\x3a\x79\x7a"
6527dce5981SNicolai Stange 	"\xbc\x0a\xb1\x82\xb3\x24\xfb\x61\xd1\x08\xa9\x4b\xb2\xc8\xe3\xfb"
6537dce5981SNicolai Stange 	"\xb9\x6a\xda\xb7\x60\xd7\xf4\x68\x1d\x4f\x42\xa3\xde\x39\x4d\xf4"
6547dce5981SNicolai Stange 	"\xae\x56\xed\xe7\x63\x72\xbb\x19\x0b\x07\xa7\xc8\xee\x0a\x6d\x70"
6557dce5981SNicolai Stange 	"\x9e\x02\xfc\xe1\xcd\xf7\xe2\xec\xc0\x34\x04\xcd\x28\x34\x2f\x61"
6567dce5981SNicolai Stange 	"\x91\x72\xfe\x9c\xe9\x85\x83\xff\x8e\x4f\x12\x32\xee\xf2\x81\x83"
6577dce5981SNicolai Stange 	"\xc3\xfe\x3b\x1b\x4c\x6f\xad\x73\x3b\xb5\xfc\xbc\x2e\xc2\x20\x05"
6587dce5981SNicolai Stange 	"\xc5\x8e\xf1\x83\x7d\x16\x83\xb2\xc6\xf3\x4a\x26\xc1\xb2\xef\xfa"
6597dce5981SNicolai Stange 	"\x88\x6b\x42\x38\x61\x1f\xcf\xdc\xde\x35\x5b\x3b\x65\x19\x03\x5b"
6607dce5981SNicolai Stange 	"\xbc\x34\xf4\xde\xf9\x9c\x02\x38\x61\xb4\x6f\xc9\xd6\xe6\xc9\x07"
6617dce5981SNicolai Stange 	"\x7a\xd9\x1d\x26\x91\xf7\xf7\xee\x59\x8c\xb0\xfa\xc1\x86\xd9\x1c"
6627dce5981SNicolai Stange 	"\xae\xfe\x13\x09\x85\x13\x92\x70\xb4\x13\x0c\x93\xbc\x43\x79\x44"
6637dce5981SNicolai Stange 	"\xf4\xfd\x44\x52\xe2\xd7\x4d\xd3\x64\xf2\xe2\x1e\x71\xf5\x4b\xff"
6647dce5981SNicolai Stange 	"\x5c\xae\x82\xab\x9c\x9d\xf6\x9e\xe8\x6d\x2b\xc5\x22\x36\x3a\x0d"
6657dce5981SNicolai Stange 	"\xab\xc5\x21\x97\x9b\x0d\xea\xda\x1d\xbf\x9a\x42\xd5\xc4\x48\x4e"
6667dce5981SNicolai Stange 	"\x0a\xbc\xd0\x6b\xfa\x53\xdd\xef\x3c\x1b\x20\xee\x3f\xd5\x9d\x7c"
6677dce5981SNicolai Stange 	"\x25\xe4\x1d\x2b\x66\xc6\x2e\x37\xff\xff\xff\xff\xff\xff\xff\xff",
6687dce5981SNicolai Stange };
6697dce5981SNicolai Stange 
6707dce5981SNicolai Stange static const struct dh_safe_prime ffdhe4096_prime = {
6717dce5981SNicolai Stange 	.max_strength = 152,
6727dce5981SNicolai Stange 	.p_size = 512,
6737dce5981SNicolai Stange 	.p =
6747dce5981SNicolai Stange 	"\xff\xff\xff\xff\xff\xff\xff\xff\xad\xf8\x54\x58\xa2\xbb\x4a\x9a"
6757dce5981SNicolai Stange 	"\xaf\xdc\x56\x20\x27\x3d\x3c\xf1\xd8\xb9\xc5\x83\xce\x2d\x36\x95"
6767dce5981SNicolai Stange 	"\xa9\xe1\x36\x41\x14\x64\x33\xfb\xcc\x93\x9d\xce\x24\x9b\x3e\xf9"
6777dce5981SNicolai Stange 	"\x7d\x2f\xe3\x63\x63\x0c\x75\xd8\xf6\x81\xb2\x02\xae\xc4\x61\x7a"
6787dce5981SNicolai Stange 	"\xd3\xdf\x1e\xd5\xd5\xfd\x65\x61\x24\x33\xf5\x1f\x5f\x06\x6e\xd0"
6797dce5981SNicolai Stange 	"\x85\x63\x65\x55\x3d\xed\x1a\xf3\xb5\x57\x13\x5e\x7f\x57\xc9\x35"
6807dce5981SNicolai Stange 	"\x98\x4f\x0c\x70\xe0\xe6\x8b\x77\xe2\xa6\x89\xda\xf3\xef\xe8\x72"
6817dce5981SNicolai Stange 	"\x1d\xf1\x58\xa1\x36\xad\xe7\x35\x30\xac\xca\x4f\x48\x3a\x79\x7a"
6827dce5981SNicolai Stange 	"\xbc\x0a\xb1\x82\xb3\x24\xfb\x61\xd1\x08\xa9\x4b\xb2\xc8\xe3\xfb"
6837dce5981SNicolai Stange 	"\xb9\x6a\xda\xb7\x60\xd7\xf4\x68\x1d\x4f\x42\xa3\xde\x39\x4d\xf4"
6847dce5981SNicolai Stange 	"\xae\x56\xed\xe7\x63\x72\xbb\x19\x0b\x07\xa7\xc8\xee\x0a\x6d\x70"
6857dce5981SNicolai Stange 	"\x9e\x02\xfc\xe1\xcd\xf7\xe2\xec\xc0\x34\x04\xcd\x28\x34\x2f\x61"
6867dce5981SNicolai Stange 	"\x91\x72\xfe\x9c\xe9\x85\x83\xff\x8e\x4f\x12\x32\xee\xf2\x81\x83"
6877dce5981SNicolai Stange 	"\xc3\xfe\x3b\x1b\x4c\x6f\xad\x73\x3b\xb5\xfc\xbc\x2e\xc2\x20\x05"
6887dce5981SNicolai Stange 	"\xc5\x8e\xf1\x83\x7d\x16\x83\xb2\xc6\xf3\x4a\x26\xc1\xb2\xef\xfa"
6897dce5981SNicolai Stange 	"\x88\x6b\x42\x38\x61\x1f\xcf\xdc\xde\x35\x5b\x3b\x65\x19\x03\x5b"
6907dce5981SNicolai Stange 	"\xbc\x34\xf4\xde\xf9\x9c\x02\x38\x61\xb4\x6f\xc9\xd6\xe6\xc9\x07"
6917dce5981SNicolai Stange 	"\x7a\xd9\x1d\x26\x91\xf7\xf7\xee\x59\x8c\xb0\xfa\xc1\x86\xd9\x1c"
6927dce5981SNicolai Stange 	"\xae\xfe\x13\x09\x85\x13\x92\x70\xb4\x13\x0c\x93\xbc\x43\x79\x44"
6937dce5981SNicolai Stange 	"\xf4\xfd\x44\x52\xe2\xd7\x4d\xd3\x64\xf2\xe2\x1e\x71\xf5\x4b\xff"
6947dce5981SNicolai Stange 	"\x5c\xae\x82\xab\x9c\x9d\xf6\x9e\xe8\x6d\x2b\xc5\x22\x36\x3a\x0d"
6957dce5981SNicolai Stange 	"\xab\xc5\x21\x97\x9b\x0d\xea\xda\x1d\xbf\x9a\x42\xd5\xc4\x48\x4e"
6967dce5981SNicolai Stange 	"\x0a\xbc\xd0\x6b\xfa\x53\xdd\xef\x3c\x1b\x20\xee\x3f\xd5\x9d\x7c"
6977dce5981SNicolai Stange 	"\x25\xe4\x1d\x2b\x66\x9e\x1e\xf1\x6e\x6f\x52\xc3\x16\x4d\xf4\xfb"
6987dce5981SNicolai Stange 	"\x79\x30\xe9\xe4\xe5\x88\x57\xb6\xac\x7d\x5f\x42\xd6\x9f\x6d\x18"
6997dce5981SNicolai Stange 	"\x77\x63\xcf\x1d\x55\x03\x40\x04\x87\xf5\x5b\xa5\x7e\x31\xcc\x7a"
7007dce5981SNicolai Stange 	"\x71\x35\xc8\x86\xef\xb4\x31\x8a\xed\x6a\x1e\x01\x2d\x9e\x68\x32"
7017dce5981SNicolai Stange 	"\xa9\x07\x60\x0a\x91\x81\x30\xc4\x6d\xc7\x78\xf9\x71\xad\x00\x38"
7027dce5981SNicolai Stange 	"\x09\x29\x99\xa3\x33\xcb\x8b\x7a\x1a\x1d\xb9\x3d\x71\x40\x00\x3c"
7037dce5981SNicolai Stange 	"\x2a\x4e\xce\xa9\xf9\x8d\x0a\xcc\x0a\x82\x91\xcd\xce\xc9\x7d\xcf"
7047dce5981SNicolai Stange 	"\x8e\xc9\xb5\x5a\x7f\x88\xa4\x6b\x4d\xb5\xa8\x51\xf4\x41\x82\xe1"
7057dce5981SNicolai Stange 	"\xc6\x8a\x00\x7e\x5e\x65\x5f\x6a\xff\xff\xff\xff\xff\xff\xff\xff",
7067dce5981SNicolai Stange };
7077dce5981SNicolai Stange 
7087dce5981SNicolai Stange static const struct dh_safe_prime ffdhe6144_prime = {
7097dce5981SNicolai Stange 	.max_strength = 176,
7107dce5981SNicolai Stange 	.p_size = 768,
7117dce5981SNicolai Stange 	.p =
7127dce5981SNicolai Stange 	"\xff\xff\xff\xff\xff\xff\xff\xff\xad\xf8\x54\x58\xa2\xbb\x4a\x9a"
7137dce5981SNicolai Stange 	"\xaf\xdc\x56\x20\x27\x3d\x3c\xf1\xd8\xb9\xc5\x83\xce\x2d\x36\x95"
7147dce5981SNicolai Stange 	"\xa9\xe1\x36\x41\x14\x64\x33\xfb\xcc\x93\x9d\xce\x24\x9b\x3e\xf9"
7157dce5981SNicolai Stange 	"\x7d\x2f\xe3\x63\x63\x0c\x75\xd8\xf6\x81\xb2\x02\xae\xc4\x61\x7a"
7167dce5981SNicolai Stange 	"\xd3\xdf\x1e\xd5\xd5\xfd\x65\x61\x24\x33\xf5\x1f\x5f\x06\x6e\xd0"
7177dce5981SNicolai Stange 	"\x85\x63\x65\x55\x3d\xed\x1a\xf3\xb5\x57\x13\x5e\x7f\x57\xc9\x35"
7187dce5981SNicolai Stange 	"\x98\x4f\x0c\x70\xe0\xe6\x8b\x77\xe2\xa6\x89\xda\xf3\xef\xe8\x72"
7197dce5981SNicolai Stange 	"\x1d\xf1\x58\xa1\x36\xad\xe7\x35\x30\xac\xca\x4f\x48\x3a\x79\x7a"
7207dce5981SNicolai Stange 	"\xbc\x0a\xb1\x82\xb3\x24\xfb\x61\xd1\x08\xa9\x4b\xb2\xc8\xe3\xfb"
7217dce5981SNicolai Stange 	"\xb9\x6a\xda\xb7\x60\xd7\xf4\x68\x1d\x4f\x42\xa3\xde\x39\x4d\xf4"
7227dce5981SNicolai Stange 	"\xae\x56\xed\xe7\x63\x72\xbb\x19\x0b\x07\xa7\xc8\xee\x0a\x6d\x70"
7237dce5981SNicolai Stange 	"\x9e\x02\xfc\xe1\xcd\xf7\xe2\xec\xc0\x34\x04\xcd\x28\x34\x2f\x61"
7247dce5981SNicolai Stange 	"\x91\x72\xfe\x9c\xe9\x85\x83\xff\x8e\x4f\x12\x32\xee\xf2\x81\x83"
7257dce5981SNicolai Stange 	"\xc3\xfe\x3b\x1b\x4c\x6f\xad\x73\x3b\xb5\xfc\xbc\x2e\xc2\x20\x05"
7267dce5981SNicolai Stange 	"\xc5\x8e\xf1\x83\x7d\x16\x83\xb2\xc6\xf3\x4a\x26\xc1\xb2\xef\xfa"
7277dce5981SNicolai Stange 	"\x88\x6b\x42\x38\x61\x1f\xcf\xdc\xde\x35\x5b\x3b\x65\x19\x03\x5b"
7287dce5981SNicolai Stange 	"\xbc\x34\xf4\xde\xf9\x9c\x02\x38\x61\xb4\x6f\xc9\xd6\xe6\xc9\x07"
7297dce5981SNicolai Stange 	"\x7a\xd9\x1d\x26\x91\xf7\xf7\xee\x59\x8c\xb0\xfa\xc1\x86\xd9\x1c"
7307dce5981SNicolai Stange 	"\xae\xfe\x13\x09\x85\x13\x92\x70\xb4\x13\x0c\x93\xbc\x43\x79\x44"
7317dce5981SNicolai Stange 	"\xf4\xfd\x44\x52\xe2\xd7\x4d\xd3\x64\xf2\xe2\x1e\x71\xf5\x4b\xff"
7327dce5981SNicolai Stange 	"\x5c\xae\x82\xab\x9c\x9d\xf6\x9e\xe8\x6d\x2b\xc5\x22\x36\x3a\x0d"
7337dce5981SNicolai Stange 	"\xab\xc5\x21\x97\x9b\x0d\xea\xda\x1d\xbf\x9a\x42\xd5\xc4\x48\x4e"
7347dce5981SNicolai Stange 	"\x0a\xbc\xd0\x6b\xfa\x53\xdd\xef\x3c\x1b\x20\xee\x3f\xd5\x9d\x7c"
7357dce5981SNicolai Stange 	"\x25\xe4\x1d\x2b\x66\x9e\x1e\xf1\x6e\x6f\x52\xc3\x16\x4d\xf4\xfb"
7367dce5981SNicolai Stange 	"\x79\x30\xe9\xe4\xe5\x88\x57\xb6\xac\x7d\x5f\x42\xd6\x9f\x6d\x18"
7377dce5981SNicolai Stange 	"\x77\x63\xcf\x1d\x55\x03\x40\x04\x87\xf5\x5b\xa5\x7e\x31\xcc\x7a"
7387dce5981SNicolai Stange 	"\x71\x35\xc8\x86\xef\xb4\x31\x8a\xed\x6a\x1e\x01\x2d\x9e\x68\x32"
7397dce5981SNicolai Stange 	"\xa9\x07\x60\x0a\x91\x81\x30\xc4\x6d\xc7\x78\xf9\x71\xad\x00\x38"
7407dce5981SNicolai Stange 	"\x09\x29\x99\xa3\x33\xcb\x8b\x7a\x1a\x1d\xb9\x3d\x71\x40\x00\x3c"
7417dce5981SNicolai Stange 	"\x2a\x4e\xce\xa9\xf9\x8d\x0a\xcc\x0a\x82\x91\xcd\xce\xc9\x7d\xcf"
7427dce5981SNicolai Stange 	"\x8e\xc9\xb5\x5a\x7f\x88\xa4\x6b\x4d\xb5\xa8\x51\xf4\x41\x82\xe1"
7437dce5981SNicolai Stange 	"\xc6\x8a\x00\x7e\x5e\x0d\xd9\x02\x0b\xfd\x64\xb6\x45\x03\x6c\x7a"
7447dce5981SNicolai Stange 	"\x4e\x67\x7d\x2c\x38\x53\x2a\x3a\x23\xba\x44\x42\xca\xf5\x3e\xa6"
7457dce5981SNicolai Stange 	"\x3b\xb4\x54\x32\x9b\x76\x24\xc8\x91\x7b\xdd\x64\xb1\xc0\xfd\x4c"
7467dce5981SNicolai Stange 	"\xb3\x8e\x8c\x33\x4c\x70\x1c\x3a\xcd\xad\x06\x57\xfc\xcf\xec\x71"
7477dce5981SNicolai Stange 	"\x9b\x1f\x5c\x3e\x4e\x46\x04\x1f\x38\x81\x47\xfb\x4c\xfd\xb4\x77"
7487dce5981SNicolai Stange 	"\xa5\x24\x71\xf7\xa9\xa9\x69\x10\xb8\x55\x32\x2e\xdb\x63\x40\xd8"
7497dce5981SNicolai Stange 	"\xa0\x0e\xf0\x92\x35\x05\x11\xe3\x0a\xbe\xc1\xff\xf9\xe3\xa2\x6e"
7507dce5981SNicolai Stange 	"\x7f\xb2\x9f\x8c\x18\x30\x23\xc3\x58\x7e\x38\xda\x00\x77\xd9\xb4"
7517dce5981SNicolai Stange 	"\x76\x3e\x4e\x4b\x94\xb2\xbb\xc1\x94\xc6\x65\x1e\x77\xca\xf9\x92"
7527dce5981SNicolai Stange 	"\xee\xaa\xc0\x23\x2a\x28\x1b\xf6\xb3\xa7\x39\xc1\x22\x61\x16\x82"
7537dce5981SNicolai Stange 	"\x0a\xe8\xdb\x58\x47\xa6\x7c\xbe\xf9\xc9\x09\x1b\x46\x2d\x53\x8c"
7547dce5981SNicolai Stange 	"\xd7\x2b\x03\x74\x6a\xe7\x7f\x5e\x62\x29\x2c\x31\x15\x62\xa8\x46"
7557dce5981SNicolai Stange 	"\x50\x5d\xc8\x2d\xb8\x54\x33\x8a\xe4\x9f\x52\x35\xc9\x5b\x91\x17"
7567dce5981SNicolai Stange 	"\x8c\xcf\x2d\xd5\xca\xce\xf4\x03\xec\x9d\x18\x10\xc6\x27\x2b\x04"
7577dce5981SNicolai Stange 	"\x5b\x3b\x71\xf9\xdc\x6b\x80\xd6\x3f\xdd\x4a\x8e\x9a\xdb\x1e\x69"
7587dce5981SNicolai Stange 	"\x62\xa6\x95\x26\xd4\x31\x61\xc1\xa4\x1d\x57\x0d\x79\x38\xda\xd4"
7597dce5981SNicolai Stange 	"\xa4\x0e\x32\x9c\xd0\xe4\x0e\x65\xff\xff\xff\xff\xff\xff\xff\xff",
7607dce5981SNicolai Stange };
7617dce5981SNicolai Stange 
7627dce5981SNicolai Stange static const struct dh_safe_prime ffdhe8192_prime = {
7637dce5981SNicolai Stange 	.max_strength = 200,
7647dce5981SNicolai Stange 	.p_size = 1024,
7657dce5981SNicolai Stange 	.p =
7667dce5981SNicolai Stange 	"\xff\xff\xff\xff\xff\xff\xff\xff\xad\xf8\x54\x58\xa2\xbb\x4a\x9a"
7677dce5981SNicolai Stange 	"\xaf\xdc\x56\x20\x27\x3d\x3c\xf1\xd8\xb9\xc5\x83\xce\x2d\x36\x95"
7687dce5981SNicolai Stange 	"\xa9\xe1\x36\x41\x14\x64\x33\xfb\xcc\x93\x9d\xce\x24\x9b\x3e\xf9"
7697dce5981SNicolai Stange 	"\x7d\x2f\xe3\x63\x63\x0c\x75\xd8\xf6\x81\xb2\x02\xae\xc4\x61\x7a"
7707dce5981SNicolai Stange 	"\xd3\xdf\x1e\xd5\xd5\xfd\x65\x61\x24\x33\xf5\x1f\x5f\x06\x6e\xd0"
7717dce5981SNicolai Stange 	"\x85\x63\x65\x55\x3d\xed\x1a\xf3\xb5\x57\x13\x5e\x7f\x57\xc9\x35"
7727dce5981SNicolai Stange 	"\x98\x4f\x0c\x70\xe0\xe6\x8b\x77\xe2\xa6\x89\xda\xf3\xef\xe8\x72"
7737dce5981SNicolai Stange 	"\x1d\xf1\x58\xa1\x36\xad\xe7\x35\x30\xac\xca\x4f\x48\x3a\x79\x7a"
7747dce5981SNicolai Stange 	"\xbc\x0a\xb1\x82\xb3\x24\xfb\x61\xd1\x08\xa9\x4b\xb2\xc8\xe3\xfb"
7757dce5981SNicolai Stange 	"\xb9\x6a\xda\xb7\x60\xd7\xf4\x68\x1d\x4f\x42\xa3\xde\x39\x4d\xf4"
7767dce5981SNicolai Stange 	"\xae\x56\xed\xe7\x63\x72\xbb\x19\x0b\x07\xa7\xc8\xee\x0a\x6d\x70"
7777dce5981SNicolai Stange 	"\x9e\x02\xfc\xe1\xcd\xf7\xe2\xec\xc0\x34\x04\xcd\x28\x34\x2f\x61"
7787dce5981SNicolai Stange 	"\x91\x72\xfe\x9c\xe9\x85\x83\xff\x8e\x4f\x12\x32\xee\xf2\x81\x83"
7797dce5981SNicolai Stange 	"\xc3\xfe\x3b\x1b\x4c\x6f\xad\x73\x3b\xb5\xfc\xbc\x2e\xc2\x20\x05"
7807dce5981SNicolai Stange 	"\xc5\x8e\xf1\x83\x7d\x16\x83\xb2\xc6\xf3\x4a\x26\xc1\xb2\xef\xfa"
7817dce5981SNicolai Stange 	"\x88\x6b\x42\x38\x61\x1f\xcf\xdc\xde\x35\x5b\x3b\x65\x19\x03\x5b"
7827dce5981SNicolai Stange 	"\xbc\x34\xf4\xde\xf9\x9c\x02\x38\x61\xb4\x6f\xc9\xd6\xe6\xc9\x07"
7837dce5981SNicolai Stange 	"\x7a\xd9\x1d\x26\x91\xf7\xf7\xee\x59\x8c\xb0\xfa\xc1\x86\xd9\x1c"
7847dce5981SNicolai Stange 	"\xae\xfe\x13\x09\x85\x13\x92\x70\xb4\x13\x0c\x93\xbc\x43\x79\x44"
7857dce5981SNicolai Stange 	"\xf4\xfd\x44\x52\xe2\xd7\x4d\xd3\x64\xf2\xe2\x1e\x71\xf5\x4b\xff"
7867dce5981SNicolai Stange 	"\x5c\xae\x82\xab\x9c\x9d\xf6\x9e\xe8\x6d\x2b\xc5\x22\x36\x3a\x0d"
7877dce5981SNicolai Stange 	"\xab\xc5\x21\x97\x9b\x0d\xea\xda\x1d\xbf\x9a\x42\xd5\xc4\x48\x4e"
7887dce5981SNicolai Stange 	"\x0a\xbc\xd0\x6b\xfa\x53\xdd\xef\x3c\x1b\x20\xee\x3f\xd5\x9d\x7c"
7897dce5981SNicolai Stange 	"\x25\xe4\x1d\x2b\x66\x9e\x1e\xf1\x6e\x6f\x52\xc3\x16\x4d\xf4\xfb"
7907dce5981SNicolai Stange 	"\x79\x30\xe9\xe4\xe5\x88\x57\xb6\xac\x7d\x5f\x42\xd6\x9f\x6d\x18"
7917dce5981SNicolai Stange 	"\x77\x63\xcf\x1d\x55\x03\x40\x04\x87\xf5\x5b\xa5\x7e\x31\xcc\x7a"
7927dce5981SNicolai Stange 	"\x71\x35\xc8\x86\xef\xb4\x31\x8a\xed\x6a\x1e\x01\x2d\x9e\x68\x32"
7937dce5981SNicolai Stange 	"\xa9\x07\x60\x0a\x91\x81\x30\xc4\x6d\xc7\x78\xf9\x71\xad\x00\x38"
7947dce5981SNicolai Stange 	"\x09\x29\x99\xa3\x33\xcb\x8b\x7a\x1a\x1d\xb9\x3d\x71\x40\x00\x3c"
7957dce5981SNicolai Stange 	"\x2a\x4e\xce\xa9\xf9\x8d\x0a\xcc\x0a\x82\x91\xcd\xce\xc9\x7d\xcf"
7967dce5981SNicolai Stange 	"\x8e\xc9\xb5\x5a\x7f\x88\xa4\x6b\x4d\xb5\xa8\x51\xf4\x41\x82\xe1"
7977dce5981SNicolai Stange 	"\xc6\x8a\x00\x7e\x5e\x0d\xd9\x02\x0b\xfd\x64\xb6\x45\x03\x6c\x7a"
7987dce5981SNicolai Stange 	"\x4e\x67\x7d\x2c\x38\x53\x2a\x3a\x23\xba\x44\x42\xca\xf5\x3e\xa6"
7997dce5981SNicolai Stange 	"\x3b\xb4\x54\x32\x9b\x76\x24\xc8\x91\x7b\xdd\x64\xb1\xc0\xfd\x4c"
8007dce5981SNicolai Stange 	"\xb3\x8e\x8c\x33\x4c\x70\x1c\x3a\xcd\xad\x06\x57\xfc\xcf\xec\x71"
8017dce5981SNicolai Stange 	"\x9b\x1f\x5c\x3e\x4e\x46\x04\x1f\x38\x81\x47\xfb\x4c\xfd\xb4\x77"
8027dce5981SNicolai Stange 	"\xa5\x24\x71\xf7\xa9\xa9\x69\x10\xb8\x55\x32\x2e\xdb\x63\x40\xd8"
8037dce5981SNicolai Stange 	"\xa0\x0e\xf0\x92\x35\x05\x11\xe3\x0a\xbe\xc1\xff\xf9\xe3\xa2\x6e"
8047dce5981SNicolai Stange 	"\x7f\xb2\x9f\x8c\x18\x30\x23\xc3\x58\x7e\x38\xda\x00\x77\xd9\xb4"
8057dce5981SNicolai Stange 	"\x76\x3e\x4e\x4b\x94\xb2\xbb\xc1\x94\xc6\x65\x1e\x77\xca\xf9\x92"
8067dce5981SNicolai Stange 	"\xee\xaa\xc0\x23\x2a\x28\x1b\xf6\xb3\xa7\x39\xc1\x22\x61\x16\x82"
8077dce5981SNicolai Stange 	"\x0a\xe8\xdb\x58\x47\xa6\x7c\xbe\xf9\xc9\x09\x1b\x46\x2d\x53\x8c"
8087dce5981SNicolai Stange 	"\xd7\x2b\x03\x74\x6a\xe7\x7f\x5e\x62\x29\x2c\x31\x15\x62\xa8\x46"
8097dce5981SNicolai Stange 	"\x50\x5d\xc8\x2d\xb8\x54\x33\x8a\xe4\x9f\x52\x35\xc9\x5b\x91\x17"
8107dce5981SNicolai Stange 	"\x8c\xcf\x2d\xd5\xca\xce\xf4\x03\xec\x9d\x18\x10\xc6\x27\x2b\x04"
8117dce5981SNicolai Stange 	"\x5b\x3b\x71\xf9\xdc\x6b\x80\xd6\x3f\xdd\x4a\x8e\x9a\xdb\x1e\x69"
8127dce5981SNicolai Stange 	"\x62\xa6\x95\x26\xd4\x31\x61\xc1\xa4\x1d\x57\x0d\x79\x38\xda\xd4"
8137dce5981SNicolai Stange 	"\xa4\x0e\x32\x9c\xcf\xf4\x6a\xaa\x36\xad\x00\x4c\xf6\x00\xc8\x38"
8147dce5981SNicolai Stange 	"\x1e\x42\x5a\x31\xd9\x51\xae\x64\xfd\xb2\x3f\xce\xc9\x50\x9d\x43"
8157dce5981SNicolai Stange 	"\x68\x7f\xeb\x69\xed\xd1\xcc\x5e\x0b\x8c\xc3\xbd\xf6\x4b\x10\xef"
8167dce5981SNicolai Stange 	"\x86\xb6\x31\x42\xa3\xab\x88\x29\x55\x5b\x2f\x74\x7c\x93\x26\x65"
8177dce5981SNicolai Stange 	"\xcb\x2c\x0f\x1c\xc0\x1b\xd7\x02\x29\x38\x88\x39\xd2\xaf\x05\xe4"
8187dce5981SNicolai Stange 	"\x54\x50\x4a\xc7\x8b\x75\x82\x82\x28\x46\xc0\xba\x35\xc3\x5f\x5c"
8197dce5981SNicolai Stange 	"\x59\x16\x0c\xc0\x46\xfd\x82\x51\x54\x1f\xc6\x8c\x9c\x86\xb0\x22"
8207dce5981SNicolai Stange 	"\xbb\x70\x99\x87\x6a\x46\x0e\x74\x51\xa8\xa9\x31\x09\x70\x3f\xee"
8217dce5981SNicolai Stange 	"\x1c\x21\x7e\x6c\x38\x26\xe5\x2c\x51\xaa\x69\x1e\x0e\x42\x3c\xfc"
8227dce5981SNicolai Stange 	"\x99\xe9\xe3\x16\x50\xc1\x21\x7b\x62\x48\x16\xcd\xad\x9a\x95\xf9"
8237dce5981SNicolai Stange 	"\xd5\xb8\x01\x94\x88\xd9\xc0\xa0\xa1\xfe\x30\x75\xa5\x77\xe2\x31"
8247dce5981SNicolai Stange 	"\x83\xf8\x1d\x4a\x3f\x2f\xa4\x57\x1e\xfc\x8c\xe0\xba\x8a\x4f\xe8"
8257dce5981SNicolai Stange 	"\xb6\x85\x5d\xfe\x72\xb0\xa6\x6e\xde\xd2\xfb\xab\xfb\xe5\x8a\x30"
8267dce5981SNicolai Stange 	"\xfa\xfa\xbe\x1c\x5d\x71\xa8\x7e\x2f\x74\x1e\xf8\xc1\xfe\x86\xfe"
8277dce5981SNicolai Stange 	"\xa6\xbb\xfd\xe5\x30\x67\x7f\x0d\x97\xd1\x1d\x49\xf7\xa8\x44\x3d"
8287dce5981SNicolai Stange 	"\x08\x22\xe5\x06\xa9\xf4\x61\x4e\x01\x1e\x2a\x94\x83\x8f\xf8\x8c"
8297dce5981SNicolai Stange 	"\xd6\x8c\x8b\xb7\xc5\xc6\x42\x4c\xff\xff\xff\xff\xff\xff\xff\xff",
8307dce5981SNicolai Stange };
8317dce5981SNicolai Stange 
dh_ffdhe2048_create(struct crypto_template * tmpl,struct rtattr ** tb)8327dce5981SNicolai Stange static int dh_ffdhe2048_create(struct crypto_template *tmpl,
8337dce5981SNicolai Stange 			       struct rtattr **tb)
8347dce5981SNicolai Stange {
8357dce5981SNicolai Stange 	return  __dh_safe_prime_create(tmpl, tb, &ffdhe2048_prime);
8367dce5981SNicolai Stange }
8377dce5981SNicolai Stange 
dh_ffdhe3072_create(struct crypto_template * tmpl,struct rtattr ** tb)8387dce5981SNicolai Stange static int dh_ffdhe3072_create(struct crypto_template *tmpl,
8397dce5981SNicolai Stange 			       struct rtattr **tb)
8407dce5981SNicolai Stange {
8417dce5981SNicolai Stange 	return  __dh_safe_prime_create(tmpl, tb, &ffdhe3072_prime);
8427dce5981SNicolai Stange }
8437dce5981SNicolai Stange 
dh_ffdhe4096_create(struct crypto_template * tmpl,struct rtattr ** tb)8447dce5981SNicolai Stange static int dh_ffdhe4096_create(struct crypto_template *tmpl,
8457dce5981SNicolai Stange 			       struct rtattr **tb)
8467dce5981SNicolai Stange {
8477dce5981SNicolai Stange 	return  __dh_safe_prime_create(tmpl, tb, &ffdhe4096_prime);
8487dce5981SNicolai Stange }
8497dce5981SNicolai Stange 
dh_ffdhe6144_create(struct crypto_template * tmpl,struct rtattr ** tb)8507dce5981SNicolai Stange static int dh_ffdhe6144_create(struct crypto_template *tmpl,
8517dce5981SNicolai Stange 			       struct rtattr **tb)
8527dce5981SNicolai Stange {
8537dce5981SNicolai Stange 	return  __dh_safe_prime_create(tmpl, tb, &ffdhe6144_prime);
8547dce5981SNicolai Stange }
8557dce5981SNicolai Stange 
dh_ffdhe8192_create(struct crypto_template * tmpl,struct rtattr ** tb)8567dce5981SNicolai Stange static int dh_ffdhe8192_create(struct crypto_template *tmpl,
8577dce5981SNicolai Stange 			       struct rtattr **tb)
8587dce5981SNicolai Stange {
8597dce5981SNicolai Stange 	return  __dh_safe_prime_create(tmpl, tb, &ffdhe8192_prime);
8607dce5981SNicolai Stange }
8617dce5981SNicolai Stange 
8627dce5981SNicolai Stange static struct crypto_template crypto_ffdhe_templates[] = {
8637dce5981SNicolai Stange 	{
8647dce5981SNicolai Stange 		.name = "ffdhe2048",
8657dce5981SNicolai Stange 		.create = dh_ffdhe2048_create,
8667dce5981SNicolai Stange 		.module = THIS_MODULE,
8677dce5981SNicolai Stange 	},
8687dce5981SNicolai Stange 	{
8697dce5981SNicolai Stange 		.name = "ffdhe3072",
8707dce5981SNicolai Stange 		.create = dh_ffdhe3072_create,
8717dce5981SNicolai Stange 		.module = THIS_MODULE,
8727dce5981SNicolai Stange 	},
8737dce5981SNicolai Stange 	{
8747dce5981SNicolai Stange 		.name = "ffdhe4096",
8757dce5981SNicolai Stange 		.create = dh_ffdhe4096_create,
8767dce5981SNicolai Stange 		.module = THIS_MODULE,
8777dce5981SNicolai Stange 	},
8787dce5981SNicolai Stange 	{
8797dce5981SNicolai Stange 		.name = "ffdhe6144",
8807dce5981SNicolai Stange 		.create = dh_ffdhe6144_create,
8817dce5981SNicolai Stange 		.module = THIS_MODULE,
8827dce5981SNicolai Stange 	},
8837dce5981SNicolai Stange 	{
8847dce5981SNicolai Stange 		.name = "ffdhe8192",
8857dce5981SNicolai Stange 		.create = dh_ffdhe8192_create,
8867dce5981SNicolai Stange 		.module = THIS_MODULE,
8877dce5981SNicolai Stange 	},
8887dce5981SNicolai Stange };
8897dce5981SNicolai Stange 
8907dce5981SNicolai Stange #else /* ! CONFIG_CRYPTO_DH_RFC7919_GROUPS */
8917dce5981SNicolai Stange 
8927dce5981SNicolai Stange static struct crypto_template crypto_ffdhe_templates[] = {};
8937dce5981SNicolai Stange 
8947dce5981SNicolai Stange #endif /* CONFIG_CRYPTO_DH_RFC7919_GROUPS */
8957dce5981SNicolai Stange 
8967dce5981SNicolai Stange 
dh_init(void)89733837be3SXiu Jianfeng static int __init dh_init(void)
898802c7f1cSSalvatore Benedetto {
8997dce5981SNicolai Stange 	int err;
9007dce5981SNicolai Stange 
9017dce5981SNicolai Stange 	err = crypto_register_kpp(&dh);
9027dce5981SNicolai Stange 	if (err)
9037dce5981SNicolai Stange 		return err;
9047dce5981SNicolai Stange 
9057dce5981SNicolai Stange 	err = crypto_register_templates(crypto_ffdhe_templates,
9067dce5981SNicolai Stange 					ARRAY_SIZE(crypto_ffdhe_templates));
9077dce5981SNicolai Stange 	if (err) {
9087dce5981SNicolai Stange 		crypto_unregister_kpp(&dh);
9097dce5981SNicolai Stange 		return err;
9107dce5981SNicolai Stange 	}
9117dce5981SNicolai Stange 
9127dce5981SNicolai Stange 	return 0;
913802c7f1cSSalvatore Benedetto }
914802c7f1cSSalvatore Benedetto 
dh_exit(void)91533837be3SXiu Jianfeng static void __exit dh_exit(void)
916802c7f1cSSalvatore Benedetto {
9177dce5981SNicolai Stange 	crypto_unregister_templates(crypto_ffdhe_templates,
9187dce5981SNicolai Stange 				    ARRAY_SIZE(crypto_ffdhe_templates));
919802c7f1cSSalvatore Benedetto 	crypto_unregister_kpp(&dh);
920802c7f1cSSalvatore Benedetto }
921802c7f1cSSalvatore Benedetto 
922c4741b23SEric Biggers subsys_initcall(dh_init);
923802c7f1cSSalvatore Benedetto module_exit(dh_exit);
924802c7f1cSSalvatore Benedetto MODULE_ALIAS_CRYPTO("dh");
925802c7f1cSSalvatore Benedetto MODULE_LICENSE("GPL");
926802c7f1cSSalvatore Benedetto MODULE_DESCRIPTION("DH generic algorithm");
927