]> git.ipfire.org Git - thirdparty/openssl.git/blame - crypto/dh/dh_check.c
Add x509 and crl corpora
[thirdparty/openssl.git] / crypto / dh / dh_check.c
CommitLineData
aa6bb135
RS
1/*
2 * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
d02b48c6 3 *
aa6bb135
RS
4 * Licensed under the OpenSSL license (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
d02b48c6
RE
8 */
9
10#include <stdio.h>
b39fc560 11#include "internal/cryptlib.h"
ec577822 12#include <openssl/bn.h>
0aeddcfa 13#include "dh_locl.h"
d02b48c6 14
1d97c843
TH
15/*-
16 * Check that p is a safe prime and
5f0477f4 17 * if g is 2, 3 or 5, check that it is a suitable generator
d02b48c6
RE
18 * where
19 * for 2, p mod 24 == 11
20 * for 3, p mod 12 == 5
21 * for 5, p mod 10 == 3 or 7
22 * should hold.
23 */
24
f971ccb2 25int DH_check(const DH *dh, int *ret)
0f113f3e
MC
26{
27 int ok = 0;
28 BN_CTX *ctx = NULL;
29 BN_ULONG l;
30 BIGNUM *t1 = NULL, *t2 = NULL;
31
32 *ret = 0;
33 ctx = BN_CTX_new();
34 if (ctx == NULL)
35 goto err;
36 BN_CTX_start(ctx);
37 t1 = BN_CTX_get(ctx);
38 if (t1 == NULL)
39 goto err;
40 t2 = BN_CTX_get(ctx);
41 if (t2 == NULL)
42 goto err;
d02b48c6 43
0f113f3e
MC
44 if (dh->q) {
45 if (BN_cmp(dh->g, BN_value_one()) <= 0)
46 *ret |= DH_NOT_SUITABLE_GENERATOR;
47 else if (BN_cmp(dh->g, dh->p) >= 0)
48 *ret |= DH_NOT_SUITABLE_GENERATOR;
49 else {
50 /* Check g^q == 1 mod p */
51 if (!BN_mod_exp(t1, dh->g, dh->q, dh->p, ctx))
52 goto err;
53 if (!BN_is_one(t1))
54 *ret |= DH_NOT_SUITABLE_GENERATOR;
55 }
56 if (!BN_is_prime_ex(dh->q, BN_prime_checks, ctx, NULL))
57 *ret |= DH_CHECK_Q_NOT_PRIME;
58 /* Check p == 1 mod q i.e. q divides p - 1 */
59 if (!BN_div(t1, t2, dh->p, dh->q, ctx))
60 goto err;
61 if (!BN_is_one(t2))
62 *ret |= DH_CHECK_INVALID_Q_VALUE;
63 if (dh->j && BN_cmp(dh->j, t1))
64 *ret |= DH_CHECK_INVALID_J_VALUE;
d02b48c6 65
0f113f3e
MC
66 } else if (BN_is_word(dh->g, DH_GENERATOR_2)) {
67 l = BN_mod_word(dh->p, 24);
68 if (l != 11)
69 *ret |= DH_NOT_SUITABLE_GENERATOR;
dfb56425 70 } else if (BN_is_word(dh->g, DH_GENERATOR_5)) {
0f113f3e
MC
71 l = BN_mod_word(dh->p, 10);
72 if ((l != 3) && (l != 7))
73 *ret |= DH_NOT_SUITABLE_GENERATOR;
74 } else
75 *ret |= DH_UNABLE_TO_CHECK_GENERATOR;
d02b48c6 76
0f113f3e
MC
77 if (!BN_is_prime_ex(dh->p, BN_prime_checks, ctx, NULL))
78 *ret |= DH_CHECK_P_NOT_PRIME;
79 else if (!dh->q) {
80 if (!BN_rshift1(t1, dh->p))
81 goto err;
82 if (!BN_is_prime_ex(t1, BN_prime_checks, ctx, NULL))
83 *ret |= DH_CHECK_P_NOT_SAFE_PRIME;
84 }
85 ok = 1;
86 err:
87 if (ctx != NULL) {
88 BN_CTX_end(ctx);
89 BN_CTX_free(ctx);
90 }
91 return (ok);
92}
bf3d6c0c
BL
93
94int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *ret)
0f113f3e
MC
95{
96 int ok = 0;
b128abc3
MC
97 BIGNUM *tmp = NULL;
98 BN_CTX *ctx = NULL;
bf3d6c0c 99
0f113f3e 100 *ret = 0;
b128abc3
MC
101 ctx = BN_CTX_new();
102 if (ctx == NULL)
0f113f3e 103 goto err;
b128abc3
MC
104 BN_CTX_start(ctx);
105 tmp = BN_CTX_get(ctx);
f5a12207 106 if (tmp == NULL || !BN_set_word(tmp, 1))
b128abc3 107 goto err;
b128abc3 108 if (BN_cmp(pub_key, tmp) <= 0)
0f113f3e 109 *ret |= DH_CHECK_PUBKEY_TOO_SMALL;
f5a12207
MC
110 if (BN_copy(tmp, dh->p) == NULL || !BN_sub_word(tmp, 1))
111 goto err;
b128abc3 112 if (BN_cmp(pub_key, tmp) >= 0)
0f113f3e 113 *ret |= DH_CHECK_PUBKEY_TOO_LARGE;
bf3d6c0c 114
b128abc3
MC
115 if (dh->q != NULL) {
116 /* Check pub_key^q == 1 mod p */
117 if (!BN_mod_exp(tmp, pub_key, dh->q, dh->p, ctx))
118 goto err;
119 if (!BN_is_one(tmp))
120 *ret |= DH_CHECK_PUBKEY_INVALID;
121 }
122
0f113f3e
MC
123 ok = 1;
124 err:
b128abc3
MC
125 if (ctx != NULL) {
126 BN_CTX_end(ctx);
127 BN_CTX_free(ctx);
128 }
0f113f3e
MC
129 return (ok);
130}