rsa_chk.c 3.8 KB
Newer Older
R
Rich Salz 已提交
1 2
/*
 * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved.
B
Bodo Möller 已提交
3
 *
R
Rich Salz 已提交
4 5 6 7
 * Licensed under the OpenSSL license (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
B
Bodo Möller 已提交
8 9 10 11
 */

#include <openssl/bn.h>
#include <openssl/err.h>
R
Richard Levitte 已提交
12
#include "rsa_locl.h"
B
Bodo Möller 已提交
13

R
Richard Levitte 已提交
14
int RSA_check_key(const RSA *key)
15 16 17
{
    return RSA_check_key_ex(key, NULL);
}
18 19

int RSA_check_key_ex(const RSA *key, BN_GENCB *cb)
20 21 22 23 24
{
    BIGNUM *i, *j, *k, *l, *m;
    BN_CTX *ctx;
    int ret = 1;

25 26
    if (key->p == NULL || key->q == NULL || key->n == NULL
            || key->e == NULL || key->d == NULL) {
27 28 29 30 31 32 33 34 35 36
        RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_VALUE_MISSING);
        return 0;
    }

    i = BN_new();
    j = BN_new();
    k = BN_new();
    l = BN_new();
    m = BN_new();
    ctx = BN_CTX_new();
37 38
    if (i == NULL || j == NULL || k == NULL || l == NULL
            || m == NULL || ctx == NULL) {
39 40 41 42 43
        ret = -1;
        RSAerr(RSA_F_RSA_CHECK_KEY_EX, ERR_R_MALLOC_FAILURE);
        goto err;
    }

44 45 46 47 48 49 50 51 52
    if (BN_is_one(key->e)) {
        ret = 0;
        RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_BAD_E_VALUE);
    }
    if (!BN_is_odd(key->e)) {
        ret = 0;
        RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_BAD_E_VALUE);
    }

53
    /* p prime? */
54 55
    if (BN_is_prime_ex(key->p, BN_prime_checks, NULL, cb) != 1) {
        ret = 0;
56 57 58 59
        RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_P_NOT_PRIME);
    }

    /* q prime? */
60 61
    if (BN_is_prime_ex(key->q, BN_prime_checks, NULL, cb) != 1) {
        ret = 0;
62 63 64 65
        RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_Q_NOT_PRIME);
    }

    /* n = p*q? */
66
    if (!BN_mul(i, key->p, key->q, ctx)) {
67 68 69 70 71 72 73 74 75
        ret = -1;
        goto err;
    }
    if (BN_cmp(i, key->n) != 0) {
        ret = 0;
        RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_N_DOES_NOT_EQUAL_P_Q);
    }

    /* d*e = 1  mod lcm(p-1,q-1)? */
76
    if (!BN_sub(i, key->p, BN_value_one())) {
77 78 79
        ret = -1;
        goto err;
    }
80
    if (!BN_sub(j, key->q, BN_value_one())) {
81 82 83 84 85
        ret = -1;
        goto err;
    }

    /* now compute k = lcm(i,j) */
86
    if (!BN_mul(l, i, j, ctx)) {
87 88 89
        ret = -1;
        goto err;
    }
90
    if (!BN_gcd(m, i, j, ctx)) {
91 92 93
        ret = -1;
        goto err;
    }
94
    if (!BN_div(k, NULL, l, m, ctx)) { /* remainder is 0 */
95 96 97
        ret = -1;
        goto err;
    }
98
    if (!BN_mod_mul(i, key->d, key->e, k, ctx)) {
99 100 101 102 103 104 105 106 107 108 109
        ret = -1;
        goto err;
    }

    if (!BN_is_one(i)) {
        ret = 0;
        RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_D_E_NOT_CONGRUENT_TO_1);
    }

    if (key->dmp1 != NULL && key->dmq1 != NULL && key->iqmp != NULL) {
        /* dmp1 = d mod (p-1)? */
110
        if (!BN_sub(i, key->p, BN_value_one())) {
111 112 113
            ret = -1;
            goto err;
        }
114
        if (!BN_mod(j, key->d, i, ctx)) {
115 116 117 118 119 120 121 122 123
            ret = -1;
            goto err;
        }
        if (BN_cmp(j, key->dmp1) != 0) {
            ret = 0;
            RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_DMP1_NOT_CONGRUENT_TO_D);
        }

        /* dmq1 = d mod (q-1)? */
124
        if (!BN_sub(i, key->q, BN_value_one())) {
125 126 127
            ret = -1;
            goto err;
        }
128
        if (!BN_mod(j, key->d, i, ctx)) {
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
            ret = -1;
            goto err;
        }
        if (BN_cmp(j, key->dmq1) != 0) {
            ret = 0;
            RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_DMQ1_NOT_CONGRUENT_TO_D);
        }

        /* iqmp = q^-1 mod p? */
        if (!BN_mod_inverse(i, key->q, key->p, ctx)) {
            ret = -1;
            goto err;
        }
        if (BN_cmp(i, key->iqmp) != 0) {
            ret = 0;
            RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_IQMP_NOT_INVERSE_OF_Q);
        }
    }
147

B
Bodo Möller 已提交
148
 err:
R
Rich Salz 已提交
149 150 151 152 153 154
    BN_free(i);
    BN_free(j);
    BN_free(k);
    BN_free(l);
    BN_free(m);
    BN_CTX_free(ctx);
155
    return ret;
156
}