Exemple #1
0
static int ubsec_dsa_verify(const unsigned char *dgst, int dgst_len,
                            DSA_SIG *sig, DSA *dsa)
{
    int v_len, d_len;
    int to_return = 0;
    int fd;
    BIGNUM v, *pv = &v;

    BN_init(&v);

    if (!bn_wexpand(pv, dsa->p->top)) {
        UBSECerr(UBSEC_F_UBSEC_DSA_VERIFY, UBSEC_R_BN_EXPAND_FAIL);
        goto err;
    }

    v_len = BN_num_bits(dsa->p);

    d_len = p_UBSEC_ubsec_bytes_to_bits((unsigned char *)dgst, dgst_len);

    if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) {
        const DSA_METHOD *meth;
        fd = 0;
        UBSECerr(UBSEC_F_UBSEC_DSA_VERIFY, UBSEC_R_UNIT_FAILURE);
        meth = DSA_OpenSSL();
        to_return = meth->dsa_do_verify(dgst, dgst_len, sig, dsa);
        goto err;
    }

    if (p_UBSEC_dsa_verify_ioctl(fd, 0, /* compute hash before signing */
                                 (unsigned char *)dgst, d_len,
                                 (unsigned char *)dsa->p->d,
                                 BN_num_bits(dsa->p),
                                 (unsigned char *)dsa->q->d,
                                 BN_num_bits(dsa->q),
                                 (unsigned char *)dsa->g->d,
                                 BN_num_bits(dsa->g),
                                 (unsigned char *)dsa->pub_key->d,
                                 BN_num_bits(dsa->pub_key),
                                 (unsigned char *)sig->r->d,
                                 BN_num_bits(sig->r),
                                 (unsigned char *)sig->s->d,
                                 BN_num_bits(sig->s), (unsigned char *)v.d,
                                 &v_len) != 0) {
        const DSA_METHOD *meth;
        UBSECerr(UBSEC_F_UBSEC_DSA_VERIFY, UBSEC_R_REQUEST_FAILED);
        p_UBSEC_ubsec_close(fd);

        meth = DSA_OpenSSL();
        to_return = meth->dsa_do_verify(dgst, dgst_len, sig, dsa);

        goto err;
    }

    p_UBSEC_ubsec_close(fd);

    to_return = 1;
 err:
    BN_clear_free(&v);
    return to_return;
}
static DSA_SIG *ubsec_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
	{
	DSA_SIG *to_return = NULL;
	int s_len = 160, r_len = 160, d_len, fd;
	BIGNUM m, *r=NULL, *s=NULL;

	BN_init(&m);

	s = BN_new();
	r = BN_new();
	if ((s == NULL) || (r==NULL))
		goto err;

	d_len = p_UBSEC_ubsec_bytes_to_bits((unsigned char *)dgst, dlen);

        if(!bn_wexpand(r, (160+BN_BITS2-1)/BN_BITS2) ||
       	   (!bn_wexpand(s, (160+BN_BITS2-1)/BN_BITS2))) {
		UBSECerr(UBSEC_F_UBSEC_DSA_DO_SIGN, UBSEC_R_BN_EXPAND_FAIL);
		goto err;
	}

	if (BN_bin2bn(dgst,dlen,&m) == NULL) {
		UBSECerr(UBSEC_F_UBSEC_DSA_DO_SIGN, UBSEC_R_BN_EXPAND_FAIL);
		goto err;
	} 

	if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) {
                const DSA_METHOD *meth;
		fd = 0;
		UBSECerr(UBSEC_F_UBSEC_DSA_DO_SIGN, UBSEC_R_UNIT_FAILURE);
                meth = DSA_OpenSSL();
                to_return =  meth->dsa_do_sign(dgst, dlen, dsa);
		goto err;
	}

	if (p_UBSEC_dsa_sign_ioctl(fd, 0, /* compute hash before signing */
		(unsigned char *)dgst, d_len,
		NULL, 0,  /* compute random value */
		(unsigned char *)dsa->p->d, BN_num_bits(dsa->p), 
		(unsigned char *)dsa->q->d, BN_num_bits(dsa->q),
		(unsigned char *)dsa->g->d, BN_num_bits(dsa->g),
		(unsigned char *)dsa->priv_key->d, BN_num_bits(dsa->priv_key),
		(unsigned char *)r->d, &r_len,
		(unsigned char *)s->d, &s_len ) != 0) {
                const DSA_METHOD *meth;

		UBSECerr(UBSEC_F_UBSEC_DSA_DO_SIGN, UBSEC_R_REQUEST_FAILED);
                p_UBSEC_ubsec_close(fd);
                meth = DSA_OpenSSL();
                to_return = meth->dsa_do_sign(dgst, dlen, dsa);

		goto err;
	}

	p_UBSEC_ubsec_close(fd);

	r->top = (160+BN_BITS2-1)/BN_BITS2;
	s->top = (160+BN_BITS2-1)/BN_BITS2;

	to_return = DSA_SIG_new();
	if(to_return == NULL) {
		UBSECerr(UBSEC_F_UBSEC_DSA_DO_SIGN, UBSEC_R_BN_EXPAND_FAIL);
		goto err;
	}

	to_return->r = r;
	to_return->s = s;

err:
	if (!to_return) {
		if (r) BN_free(r);
		if (s) BN_free(s);
	}                                 
	BN_clear_free(&m);
	return to_return;
}