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; }