554 lines
20 KiB
C
Executable File
554 lines
20 KiB
C
Executable File
/* Cryptic -- Cryptographic tools and protocols
|
|
* Copyright (C) 2009 Mikaël Ates <mates@entrouvert.com>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software Foundation,
|
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*/
|
|
|
|
#include <openssl/bn.h>
|
|
#include <openssl/rsa.h>
|
|
|
|
#include "../../errors.h"
|
|
#include "../../utils.h"
|
|
|
|
#include "clsig.h"
|
|
|
|
/**
|
|
* Load certificate should always be used by the prover to check certificate validity
|
|
* because these functions rebuild the DL representation.
|
|
**/
|
|
|
|
/**
|
|
* cryptic_clsig_load_certificate
|
|
* @A: Signature value
|
|
* @e: RSA exponent
|
|
* @v: blind factor
|
|
* @quantities: quantities signed
|
|
* @nb_quantities: number of quantities
|
|
*
|
|
* Load a certificate: tuple (A,e,v) and the quantities.
|
|
* Compute the DL representation starting using the first base.
|
|
*
|
|
* Return value: #CRYPTIC_NO_ERROR if successful, an error code otherwise.
|
|
*
|
|
**/
|
|
int
|
|
cryptic_clsig_load_certificate(CrypticClsig *clsig,
|
|
BIGNUM *A,
|
|
BIGNUM *e,
|
|
BIGNUM *v,
|
|
BIGNUM **quantities,
|
|
int nb_quantities,
|
|
int sig_checking)
|
|
{
|
|
int rc = CRYPTIC_ERROR_UNDEFINED;
|
|
|
|
BIGNUM *tmp = NULL, *two = NULL, *lg = NULL;
|
|
BN_CTX *ctx = NULL;
|
|
|
|
goto_cleanup_if_fail_with_rc_with_warning(clsig->init == 1,
|
|
CRYPTIC_CLSIG_NOT_CORRECTLY_INITIALIZED);
|
|
goto_cleanup_if_fail_with_rc_with_warning(A != NULL,
|
|
CRYPTIC_CLSIG_LOADING_CERTIFICATE_MISSING_ELEMENT);
|
|
goto_cleanup_if_fail_with_rc_with_warning(e != NULL,
|
|
CRYPTIC_CLSIG_LOADING_CERTIFICATE_MISSING_ELEMENT);
|
|
goto_cleanup_if_fail_with_rc_with_warning(v != NULL,
|
|
CRYPTIC_CLSIG_LOADING_CERTIFICATE_MISSING_ELEMENT);
|
|
goto_cleanup_if_fail_with_rc_with_warning(BN_num_bits(e) == clsig->lg_exponent,
|
|
CRYPTIC_CLSIG_EXPONENT_BAD_SIZE);
|
|
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(tmp = BN_new());
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(lg = BN_new());
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(two = BN_new());
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_set_word(two,2) == 1);
|
|
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(ctx = BN_CTX_new());
|
|
|
|
/* Take e in [2^le-1, 2^le-1 + 2^lei-1] */
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_set_word(lg,clsig->lg_exponent-1) == 1);
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_exp(tmp,two,lg, ctx));
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_set_word(lg,clsig->interval_exponent-1) == 1);
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_exp(lg,two,lg, ctx));
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_add(lg,tmp,lg));
|
|
|
|
goto_cleanup_if_fail_with_rc_with_warning(BN_ucmp(clsig->e,lg) < 0,
|
|
CRYPTIC_CLSIG_EXPONENT_BAD_SIZE);
|
|
|
|
cryptic_check_good_rc(cryptic_clsig_compute_dlrep_bulk_from_offset(clsig, quantities, 0, nb_quantities));
|
|
|
|
cryptic_release_bn(clsig->A);
|
|
cryptic_release_bn(clsig->e);
|
|
cryptic_release_bn(clsig->v);
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(clsig->A = BN_new());
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(clsig->A,A));
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(clsig->e = BN_new());
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(clsig->e,e));
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(clsig->v = BN_new());
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(clsig->v,v));
|
|
|
|
clsig->sigloaded = 1;
|
|
|
|
if (sig_checking) {
|
|
cryptic_check_good_rc(cryptic_clsig_verify_signature_not_randomized(clsig));
|
|
}
|
|
|
|
rc = CRYPTIC_NO_ERROR;
|
|
cleanup:
|
|
cryptic_release_ctx(ctx);
|
|
cryptic_release_bn(two);
|
|
cryptic_release_bn(lg);
|
|
cryptic_release_bn(tmp);
|
|
return rc;
|
|
}
|
|
|
|
/**
|
|
* cryptic_clsig_load_certificate_with_index
|
|
* @A: Signature value
|
|
* @e: RSA exponent
|
|
* @v: blind factor
|
|
* @quantities: quantities signed
|
|
* @nb_quantities: number of quantities
|
|
* @index: indicate the bases of representation
|
|
*
|
|
* Load a certificate: tuple (A,e,v) and the quantities
|
|
* Compute the DL representation using the base given by the index.
|
|
*
|
|
* Return value: #CRYPTIC_NO_ERROR if successful, an error code otherwise.
|
|
*
|
|
**/
|
|
int
|
|
cryptic_clsig_load_certificate_with_index(CrypticClsig *clsig,
|
|
BIGNUM *A,
|
|
BIGNUM *e,
|
|
BIGNUM *v,
|
|
BIGNUM **quantities,
|
|
int nb_quantities,
|
|
int* index,
|
|
int sig_checking)
|
|
{
|
|
int rc = CRYPTIC_ERROR_UNDEFINED;
|
|
|
|
BIGNUM *tmp = NULL, *two = NULL, *lg = NULL;
|
|
BN_CTX *ctx = NULL;
|
|
|
|
goto_cleanup_if_fail_with_rc_with_warning(clsig->init == 1,
|
|
CRYPTIC_CLSIG_NOT_CORRECTLY_INITIALIZED);
|
|
goto_cleanup_if_fail_with_rc_with_warning(A != NULL,
|
|
CRYPTIC_CLSIG_LOADING_CERTIFICATE_MISSING_ELEMENT);
|
|
goto_cleanup_if_fail_with_rc_with_warning(e != NULL,
|
|
CRYPTIC_CLSIG_LOADING_CERTIFICATE_MISSING_ELEMENT);
|
|
goto_cleanup_if_fail_with_rc_with_warning(v != NULL,
|
|
CRYPTIC_CLSIG_LOADING_CERTIFICATE_MISSING_ELEMENT);
|
|
goto_cleanup_if_fail_with_rc_with_warning(BN_num_bits(e) == clsig->lg_exponent,
|
|
CRYPTIC_CLSIG_EXPONENT_BAD_SIZE);
|
|
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(tmp = BN_new());
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(lg = BN_new());
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(two = BN_new());
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_set_word(two,2) == 1);
|
|
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(ctx = BN_CTX_new());
|
|
|
|
/* Take e in [2^le-1, 2^le-1 + 2^lei-1] */
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_set_word(lg,clsig->lg_exponent-1) == 1);
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_exp(tmp,two,lg, ctx));
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_set_word(lg,clsig->interval_exponent-1) == 1);
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_exp(lg,two,lg, ctx));
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_add(lg,tmp,lg));
|
|
|
|
goto_cleanup_if_fail_with_rc_with_warning(BN_ucmp(clsig->e,lg) < 0,
|
|
CRYPTIC_CLSIG_EXPONENT_BAD_SIZE);
|
|
|
|
cryptic_check_good_rc(cryptic_clsig_compute_dlrep_by_index(clsig, quantities, index, nb_quantities));
|
|
|
|
cryptic_release_bn(clsig->A);
|
|
cryptic_release_bn(clsig->e);
|
|
cryptic_release_bn(clsig->v);
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(clsig->A = BN_new());
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(clsig->A,A));
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(clsig->e = BN_new());
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(clsig->e,e));
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(clsig->v = BN_new());
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(clsig->v,v));
|
|
|
|
clsig->sigloaded = 1;
|
|
|
|
if (sig_checking) {
|
|
cryptic_check_good_rc(cryptic_clsig_verify_signature_not_randomized(clsig));
|
|
}
|
|
|
|
rc = CRYPTIC_NO_ERROR;
|
|
cleanup:
|
|
cryptic_release_ctx(ctx);
|
|
cryptic_release_bn(two);
|
|
cryptic_release_bn(lg);
|
|
cryptic_release_bn(tmp);
|
|
return rc;
|
|
}
|
|
|
|
/**
|
|
* cryptic_clsig_load_certificate_with_committed_value
|
|
* @A: Signature value
|
|
* @e: RSA exponent
|
|
* @v: blind factor
|
|
* @quantities: quantities signed
|
|
* @nb_quantities: number of quantities
|
|
* @quantities: quantities committed signed
|
|
* @nb_quantities: number of quantities committed
|
|
* @vprime: blind factor of the quantities committed
|
|
* @commitment: Representation of the quantities committed
|
|
*
|
|
* Load a certificate: tuple (A,e,v) and the quantities
|
|
* The bases for the not commited values are taken in order from the first one.
|
|
*
|
|
* Return value: #CRYPTIC_NO_ERROR if successful, an error code otherwise.
|
|
*
|
|
**/
|
|
int
|
|
cryptic_clsig_load_certificate_with_committed_value(CrypticClsig *clsig,
|
|
BIGNUM *A,
|
|
BIGNUM *e,
|
|
BIGNUM *v,
|
|
BIGNUM **quantities, int nb_quantities,
|
|
BIGNUM **quantitiesC, int nb_quantitiesC,
|
|
BIGNUM *commitment, BIGNUM *vprime)
|
|
{
|
|
int rc = CRYPTIC_ERROR_UNDEFINED;
|
|
|
|
int i;
|
|
BIGNUM *tmp = NULL;
|
|
BN_CTX *ctx = NULL;
|
|
|
|
goto_cleanup_if_fail_with_rc_with_warning(clsig->init == 1,
|
|
CRYPTIC_CLSIG_NOT_CORRECTLY_INITIALIZED);
|
|
goto_cleanup_if_fail_with_rc_with_warning(vprime != NULL,
|
|
CRYPTIC_CLSIG_MISSING_SIGN_BLIND_RANDOM);
|
|
goto_cleanup_if_fail_with_rc_with_warning(commitment != NULL,
|
|
CRYPTIC_CLSIG_MISSING_SIGN_BLIND_COMMITMENT);
|
|
goto_cleanup_if_fail_with_rc_with_warning(nb_quantitiesC > 0,
|
|
CRYPTIC_CLSIG_NO_VALID_QUANTITIES_NUMBER);
|
|
goto_cleanup_if_fail_with_rc_with_warning(quantitiesC != NULL,
|
|
CRYPTIC_CLSIG_MISSING_QUANTITIES);
|
|
for(i=0;i<nb_quantitiesC;i++){
|
|
goto_cleanup_if_fail_with_rc_with_warning(quantitiesC[i] != NULL,
|
|
CRYPTIC_CLSIG_MISSING_QUANTITIES);
|
|
goto_cleanup_if_fail_with_rc_with_warning(BN_num_bits(quantitiesC[i]) <= clsig->lg_quantities,
|
|
CRYPTIC_CLSIG_QUANTITY_TOO_LARGE);
|
|
}
|
|
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(tmp = BN_new());
|
|
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(ctx = BN_CTX_new());
|
|
|
|
cryptic_check_good_rc(cryptic_clsig_load_certificate(clsig, A, e, v, quantities, nb_quantities, 0));
|
|
|
|
/* commitment = committed_dlrep * S^vprime */
|
|
/* commitment * S^-vprime = committed_dlrep */
|
|
/* clsig->dlrep := clsig->dlrep * committed_dlrep */
|
|
/* clsig->v := clsig->v + vprime */
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_inverse(tmp,clsig->S,clsig->modulus,ctx));
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_exp(tmp,tmp,vprime,clsig->modulus,ctx) == 1);
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_mul(tmp,tmp,commitment,clsig->modulus,ctx) == 1);
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_mul(clsig->dlrep,clsig->dlrep,tmp,clsig->modulus,ctx) == 1);
|
|
|
|
clsig->sigloaded = 1;
|
|
|
|
for(i=0;i<nb_quantitiesC;i++){
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(clsig->quantities[clsig->nb_quantities+i] = BN_new());
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(clsig->quantities[clsig->nb_quantities+i],quantitiesC[i]));
|
|
}
|
|
clsig->nb_quantities = clsig->nb_quantities + nb_quantitiesC;
|
|
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_add(clsig->v,clsig->v,vprime));
|
|
|
|
rc = cryptic_clsig_verify_signature_not_randomized(clsig);
|
|
if(rc == 1){
|
|
rc = CRYPTIC_NO_ERROR;
|
|
}
|
|
cleanup:
|
|
cryptic_release_ctx(ctx);
|
|
cryptic_release_bn(tmp);
|
|
return rc;
|
|
}
|
|
|
|
/**
|
|
* cryptic_clsig_load_certificate_with_index_with_committed_value
|
|
* @A: Signature value
|
|
* @e: RSA exponent
|
|
* @v: blind factor
|
|
* @quantities: quantities signed
|
|
* @nb_quantities: number of quantities
|
|
* @quantities: quantities committed signed
|
|
* @nb_quantities: number of quantities committed
|
|
* @vprime: blind factor of the quantities committed
|
|
* @commitment: Representation of the quantities committed
|
|
* @index: index of the bases used for representation
|
|
*
|
|
* Load a certificate: tuple (A,e,v) and the quantities
|
|
* Compute the DL representation using the base given by the index for the not committed values.
|
|
* WARNING: index of the bases used for the not committed to the issuer values
|
|
*
|
|
* Return value: #CRYPTIC_NO_ERROR if successful, an error code otherwise.
|
|
*
|
|
**/
|
|
int
|
|
cryptic_clsig_load_certificate_with_index_with_committed_value(CrypticClsig *clsig,
|
|
BIGNUM *A,
|
|
BIGNUM *e,
|
|
BIGNUM *v,
|
|
BIGNUM **quantities, int nb_quantities,
|
|
BIGNUM **quantitiesC, int nb_quantitiesC,
|
|
BIGNUM *commitment, BIGNUM *vprime,
|
|
int *index)
|
|
{
|
|
|
|
int rc = CRYPTIC_ERROR_UNDEFINED;
|
|
|
|
int i;
|
|
BIGNUM *tmp = NULL;
|
|
BN_CTX *ctx = NULL;
|
|
|
|
goto_cleanup_if_fail_with_rc_with_warning(clsig->init == 1,
|
|
CRYPTIC_CLSIG_NOT_CORRECTLY_INITIALIZED);
|
|
goto_cleanup_if_fail_with_rc_with_warning(vprime != NULL,
|
|
CRYPTIC_CLSIG_MISSING_SIGN_BLIND_RANDOM);
|
|
goto_cleanup_if_fail_with_rc_with_warning(commitment != NULL,
|
|
CRYPTIC_CLSIG_MISSING_SIGN_BLIND_COMMITMENT);
|
|
goto_cleanup_if_fail_with_rc_with_warning(nb_quantitiesC > 0,
|
|
CRYPTIC_CLSIG_NO_VALID_QUANTITIES_NUMBER);
|
|
goto_cleanup_if_fail_with_rc_with_warning(quantitiesC != NULL,
|
|
CRYPTIC_CLSIG_MISSING_QUANTITIES);
|
|
for(i=0;i<nb_quantitiesC;i++){
|
|
goto_cleanup_if_fail_with_rc_with_warning(quantitiesC[i] != NULL,
|
|
CRYPTIC_CLSIG_MISSING_QUANTITIES);
|
|
goto_cleanup_if_fail_with_rc_with_warning(BN_num_bits(quantitiesC[i]) <= clsig->lg_quantities,
|
|
CRYPTIC_CLSIG_QUANTITY_TOO_LARGE);
|
|
}
|
|
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(tmp = BN_new());
|
|
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(ctx = BN_CTX_new());
|
|
|
|
cryptic_check_good_rc(cryptic_clsig_load_certificate_with_index(clsig, A, e, v, quantities, nb_quantities, index, 0));
|
|
|
|
/* commitment = committed_dlrep * S^vprime */
|
|
/* commitment * S^-vprime = committed_dlrep */
|
|
/* clsig->dlrep := clsig->dlrep * committed_dlrep */
|
|
/* clsig->v := clsig->v + vprime */
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_inverse(tmp,clsig->S,clsig->modulus,ctx));
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_exp(tmp,tmp,vprime,clsig->modulus,ctx) == 1);
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_mul(tmp,tmp,commitment,clsig->modulus,ctx) == 1);
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_mul(clsig->dlrep,clsig->dlrep,tmp,clsig->modulus,ctx) == 1);
|
|
|
|
clsig->sigloaded = 1;
|
|
|
|
for(i=0;i<nb_quantitiesC;i++){
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(clsig->quantities[clsig->nb_quantities+i] = BN_new());
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(clsig->quantities[clsig->nb_quantities+i],quantitiesC[i]));
|
|
}
|
|
clsig->nb_quantities = clsig->nb_quantities + nb_quantitiesC;
|
|
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_add(clsig->v,clsig->v,vprime));
|
|
|
|
rc = cryptic_clsig_verify_signature_not_randomized(clsig);
|
|
if(rc == 1){
|
|
rc = CRYPTIC_NO_ERROR;
|
|
}
|
|
cleanup:
|
|
cryptic_release_ctx(ctx);
|
|
cryptic_release_bn(tmp);
|
|
return rc;
|
|
}
|
|
|
|
/**
|
|
* cryptic_clsig_verify_signature_not_randomized
|
|
*
|
|
* Verify a signature value not randomized.
|
|
*
|
|
* Return value: 1 if signature valid, 0 if signature invalid, an error code otherwise.
|
|
*
|
|
**/
|
|
int
|
|
cryptic_clsig_verify_signature_not_randomized(CrypticClsig *clsig)
|
|
{
|
|
|
|
int rc = CRYPTIC_ERROR_UNDEFINED;
|
|
|
|
int res;
|
|
BIGNUM *tmp1 = NULL, *tmp2 = NULL;
|
|
BN_CTX *ctx = NULL;
|
|
BN_MONT_CTX *mont = NULL;
|
|
|
|
goto_cleanup_if_fail_with_rc_with_warning(clsig->init == 1,
|
|
CRYPTIC_CLSIG_NOT_CORRECTLY_INITIALIZED);
|
|
goto_cleanup_if_fail_with_rc_with_warning(clsig->sigloaded == 1,
|
|
CRYPTIC_CLSIG_SIGNATURE_NOT_CORRECTLY_LOADED);
|
|
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(tmp1 = BN_new());
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(tmp2 = BN_new());
|
|
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(ctx = BN_CTX_new());
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(mont=BN_MONT_CTX_new());
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_MONT_CTX_set(mont,clsig->modulus,ctx));
|
|
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_exp_mont(tmp1,clsig->S,clsig->v,clsig->modulus,ctx,mont) == 1);
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_mul(tmp1,tmp1,clsig->dlrep,clsig->modulus,ctx) == 1);
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_exp_mont(tmp2,clsig->A,clsig->e,clsig->modulus,ctx,mont) == 1);
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_mul(tmp1,tmp1,tmp2,clsig->modulus,ctx) == 1);
|
|
|
|
if (BN_ucmp(clsig->Z, tmp1) == 0){
|
|
clsig->sigverified = 1;
|
|
res = 1;
|
|
} else{
|
|
res = 0;
|
|
}
|
|
|
|
rc = CRYPTIC_NO_ERROR;
|
|
cleanup:
|
|
cryptic_release_ctx(ctx);
|
|
cryptic_release_mont(mont);
|
|
cryptic_release_bn(tmp2);
|
|
cryptic_release_bn(tmp1);
|
|
if(rc != CRYPTIC_NO_ERROR) return rc;
|
|
return res;
|
|
}
|
|
|
|
/**
|
|
* cryptic_clsig_verify_signature_not_randomized_prover
|
|
*
|
|
* Verify a signature value randomized.
|
|
*
|
|
* Return value: 1 if signature valid, 0 if signature invalid, an error code otherwise.
|
|
*
|
|
**/
|
|
int
|
|
cryptic_clsig_verify_signature_randomized(CrypticClsig *clsig)
|
|
{
|
|
|
|
int rc = CRYPTIC_ERROR_UNDEFINED;
|
|
|
|
int res;
|
|
BIGNUM *tmp1 = NULL, *tmp2 = NULL;
|
|
BN_CTX *ctx = NULL;
|
|
BN_MONT_CTX *mont = NULL;
|
|
|
|
goto_cleanup_if_fail_with_rc_with_warning(clsig->sigrandomized == 1,
|
|
CRYPTIC_CLSIG_SIGNATURE_NOT_RANDOMIZED);
|
|
goto_cleanup_if_fail_with_rc_with_warning(clsig->A_rand != NULL,
|
|
CRYPTIC_CLSIG_SIGNATURE_NOT_RANDOMIZED);
|
|
goto_cleanup_if_fail_with_rc_with_warning(clsig->e_corrected != NULL,
|
|
CRYPTIC_CLSIG_SIGNATURE_NOT_RANDOMIZED);
|
|
goto_cleanup_if_fail_with_rc_with_warning(clsig->v_rand != NULL,
|
|
CRYPTIC_CLSIG_SIGNATURE_NOT_RANDOMIZED);
|
|
goto_cleanup_if_fail_with_rc_with_warning(clsig->S != NULL,
|
|
CRYPTIC_CLSIG_SIGNATURE_NOT_RANDOMIZED);
|
|
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(tmp1 = BN_new());
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(tmp2 = BN_new());
|
|
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(ctx = BN_CTX_new());
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(mont=BN_MONT_CTX_new());
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_MONT_CTX_set(mont,clsig->modulus,ctx));
|
|
|
|
if(BN_is_negative(clsig->v_rand)){
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(tmp2,clsig->S));
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_inverse(clsig->S,clsig->S,clsig->modulus,ctx));
|
|
}
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_exp_mont(tmp1,clsig->S,clsig->v_rand,clsig->modulus,ctx,mont) == 1);
|
|
if(BN_is_negative(clsig->v_rand)) goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(clsig->S,tmp2));
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_exp_mont(tmp2,clsig->A_rand,clsig->e,clsig->modulus,ctx,mont) == 1);
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_mul(tmp1,tmp1,tmp2,clsig->modulus,ctx) == 1);
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_mul(tmp1,tmp1,clsig->dlrep,clsig->modulus,ctx) == 1);
|
|
|
|
if (BN_ucmp(clsig->Z, tmp1) == 0){
|
|
res = 1;
|
|
} else{
|
|
res = 0;
|
|
}
|
|
|
|
rc = CRYPTIC_NO_ERROR;
|
|
cleanup:
|
|
cryptic_release_ctx(ctx);
|
|
cryptic_release_mont(mont);
|
|
cryptic_release_bn(tmp2);
|
|
cryptic_release_bn(tmp1);
|
|
if(rc != CRYPTIC_NO_ERROR) return rc;
|
|
return res;
|
|
}
|
|
|
|
/**
|
|
* cryptic_clsig_verify_rsa_param
|
|
*
|
|
* Check validity of a RSA key pair.
|
|
*
|
|
* Return value: 1 if signature valid, 0 if signature invalid, an error code otherwise.
|
|
*
|
|
**/
|
|
int
|
|
cryptic_clsig_verify_rsa_param(CrypticClsig *clsig)
|
|
{
|
|
int rc = CRYPTIC_ERROR_UNDEFINED;
|
|
|
|
BIGNUM *tmp1 = NULL, *tmp2 = NULL;
|
|
BN_CTX *ctx = NULL;
|
|
RSA *key = RSA_new();
|
|
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(tmp1 = BN_new());
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(tmp2 = BN_new());
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(key->n = BN_new());
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(key->e = BN_new());
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(key->d = BN_new());
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(key->p = BN_new());
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(key->q = BN_new());
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(key->dmp1 = BN_new());
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(key->dmq1 = BN_new());
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(key->iqmp = BN_new());
|
|
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(ctx = BN_CTX_new());
|
|
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(key->n,clsig->modulus));
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(key->p,cryptic_qrg_get_p(clsig->qrg)));
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(key->q,cryptic_qrg_get_q(clsig->qrg)));
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(key->e,clsig->e));
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_copy(key->d,clsig->d));
|
|
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_sub(tmp1,cryptic_qrg_get_p(clsig->qrg),BN_value_one()));
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod(key->dmp1,key->d,tmp1,ctx));
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_sub(tmp1,key->q,BN_value_one()));
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod(key->dmq1,key->d,tmp1,ctx));
|
|
goto_cleanup_if_fail_with_rc_with_warning_openssl(BN_mod_inverse(key->iqmp,key->q,key->p,ctx));
|
|
|
|
/*if (r == 1){
|
|
printf("RSA key ok\n");
|
|
}
|
|
else if (r == 0){
|
|
printf("RSA key ko\n");
|
|
unsigned long err;
|
|
while ((err = ERR_peek_error()) != 0 ){
|
|
printf("RSA key error: %d\n", ERR_reason_error_string(err));
|
|
ERR_get_error();
|
|
}
|
|
}*/
|
|
goto_cleanup_if_fail_with_rc_with_warning(RSA_check_key(key) == 1, CRYPTIC_CLSIG_BAD_RSA_KEY_PAIR);
|
|
|
|
rc = CRYPTIC_NO_ERROR;
|
|
cleanup:
|
|
cryptic_release_ctx(ctx);
|
|
cryptic_release_bn(tmp2);
|
|
cryptic_release_bn(tmp1);
|
|
if(key) RSA_free(key);
|
|
if(rc == CRYPTIC_NO_ERROR) return 1;
|
|
return rc;
|
|
}
|