]>
Commit | Line | Data |
---|---|---|
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 | 25 | int 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 | |
94 | int 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 | } |