Deal with API changes.
[openssl.git] / crypto / engine / eng_cryptodev.c
index 59eab5a74472a6c795fb2002b24ca7cd9fc0ef63..cd362bee89967a5b99eab03e8b03fb106837e37a 100644 (file)
@@ -1,3 +1,12 @@
+/*
+ * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * 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
+ */
+
 /*
  * Copyright (c) 2002 Bob Beck <beck@openbsd.org>
  * Copyright (c) 2002 Theo de Raadt
@@ -84,9 +93,13 @@ struct dev_crypto_state {
 
 static u_int32_t cryptodev_asymfeat = 0;
 
+static RSA_METHOD *cryptodev_rsa;
 #ifndef OPENSSL_NO_DSA
 static DSA_METHOD *cryptodev_dsa = NULL;
 #endif
+#ifndef OPENSSL_NO_DH
+static DH_METHOD *cryptodev_dh;
+#endif
 
 static int get_asym_dev_crypto(void);
 static int open_dev_crypto(void);
@@ -120,13 +133,13 @@ static int cryptodev_rsa_nocrt_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa,
 static int cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa,
                                  BN_CTX *ctx);
 #ifndef OPENSSL_NO_DSA
-static int cryptodev_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a,
+static int cryptodev_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, const BIGNUM *a,
                                     const BIGNUM *p, const BIGNUM *m,
                                     BN_CTX *ctx, BN_MONT_CTX *m_ctx);
-static int cryptodev_dsa_dsa_mod_exp(DSA *dsa, BIGNUM *t1, BIGNUM *g,
-                                     BIGNUM *u1, BIGNUM *pub_key, BIGNUM *u2,
-                                     BIGNUM *p, BN_CTX *ctx,
-                                     BN_MONT_CTX *mont);
+static int cryptodev_dsa_dsa_mod_exp(DSA *dsa, BIGNUM *t1, const BIGNUM *g,
+                                     const BIGNUM *u1, const BIGNUM *pub_key,
+                                     const BIGNUM *u2, const BIGNUM *p,
+                                     BN_CTX *ctx, BN_MONT_CTX *mont);
 static DSA_SIG *cryptodev_dsa_do_sign(const unsigned char *dgst, int dlen,
                                       DSA *dsa);
 static int cryptodev_dsa_verify(const unsigned char *dgst, int dgst_len,
@@ -442,7 +455,7 @@ cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
     cryp.op = EVP_CIPHER_CTX_encrypting(ctx) ? COP_ENCRYPT : COP_DECRYPT;
 
     if (EVP_CIPHER_CTX_iv_length(ctx) > 0) {
-        cryp.iv = *(caddr_t*) EVP_CIPHER_CTX_iv(ctx);
+        cryp.iv = (caddr_t) EVP_CIPHER_CTX_iv(ctx);
         if (!EVP_CIPHER_CTX_encrypting(ctx)) {
             iiv = in + inl - EVP_CIPHER_CTX_iv_length(ctx);
             memcpy(save_iv, iiv, EVP_CIPHER_CTX_iv_length(ctx));
@@ -1176,9 +1189,15 @@ static int cryptodev_engine_destroy(ENGINE *e)
     EVP_MD_meth_free(md5_md);
     md5_md = NULL;
 # endif
+    RSA_meth_free(cryptodev_rsa);
+    cryptodev_rsa = NULL;
 #ifndef OPENSSL_NO_DSA
     DSA_meth_free(cryptodev_dsa);
     cryptodev_dsa = NULL;
+#endif
+#ifndef OPENSSL_NO_DH
+    DH_meth_free(cryptodev_dh);
+    cryptodev_dh = NULL;
 #endif
     return 1;
 }
@@ -1238,8 +1257,7 @@ static void zapparams(struct crypt_kop *kop)
     int i;
 
     for (i = 0; i < kop->crk_iparams + kop->crk_oparams; i++) {
-        if (kop->crk_param[i].crp_p)
-            free(kop->crk_param[i].crp_p);
+        OPENSSL_free(kop->crk_param[i].crp_p);
         kop->crk_param[i].crp_p = NULL;
         kop->crk_param[i].crp_nbits = 0;
     }
@@ -1252,16 +1270,24 @@ cryptodev_asym(struct crypt_kop *kop, int rlen, BIGNUM *r, int slen,
     int fd, ret = -1;
 
     if ((fd = get_asym_dev_crypto()) < 0)
-        return (ret);
+        return ret;
 
     if (r) {
-        kop->crk_param[kop->crk_iparams].crp_p = calloc(rlen, sizeof(char));
+        kop->crk_param[kop->crk_iparams].crp_p = OPENSSL_zalloc(rlen);
+        if (kop->crk_param[kop->crk_iparams].crp_p == NULL)
+            return ret;
         kop->crk_param[kop->crk_iparams].crp_nbits = rlen * 8;
         kop->crk_oparams++;
     }
     if (s) {
         kop->crk_param[kop->crk_iparams + 1].crp_p =
-            calloc(slen, sizeof(char));
+            OPENSSL_zalloc(slen);
+        /* No need to free the kop->crk_iparams parameter if it was allocated,
+         * callers of this routine have to free allocated parameters through
+         * zapparams both in case of success and failure
+         */
+        if (kop->crk_param[kop->crk_iparams+1].crp_p == NULL)
+            return ret;
         kop->crk_param[kop->crk_iparams + 1].crp_nbits = slen * 8;
         kop->crk_oparams++;
     }
@@ -1274,7 +1300,7 @@ cryptodev_asym(struct crypt_kop *kop, int rlen, BIGNUM *r, int slen,
         ret = 0;
     }
 
-    return (ret);
+    return ret;
 }
 
 static int
@@ -1327,8 +1353,8 @@ cryptodev_rsa_nocrt_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa,
                             BN_CTX *ctx)
 {
     int r;
-    BIGNUM *n = NULL;
-    BIGNUM *d = NULL;
+    const BIGNUM *n = NULL;
+    const BIGNUM *d = NULL;
 
     ctx = BN_CTX_new();
     RSA_get0_key(rsa, &n, NULL, &d);
@@ -1342,12 +1368,12 @@ cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
 {
     struct crypt_kop kop;
     int ret = 1;
-    BIGNUM *p = NULL;
-    BIGNUM *q = NULL;
-    BIGNUM *dmp1 = NULL;
-    BIGNUM *dmq1 = NULL;
-    BIGNUM *iqmp = NULL;
-    BIGNUM *n = NULL;
+    const BIGNUM *p = NULL;
+    const BIGNUM *q = NULL;
+    const BIGNUM *dmp1 = NULL;
+    const BIGNUM *dmq1 = NULL;
+    const BIGNUM *iqmp = NULL;
+    const BIGNUM *n = NULL;
 
     RSA_get0_factors(rsa, &p, &q);
     RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp);
@@ -1392,25 +1418,25 @@ cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
     return (ret);
 }
 
-static RSA_METHOD *cryptodev_rsa;
-
 #ifndef OPENSSL_NO_DSA
 static int
-cryptodev_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a, const BIGNUM *p,
+cryptodev_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
                          const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
 {
-    return (cryptodev_bn_mod_exp(r, a, p, m, ctx, m_ctx));
+    return cryptodev_bn_mod_exp(r, a, p, m, ctx, m_ctx);
 }
 
 static int
-cryptodev_dsa_dsa_mod_exp(DSA *dsa, BIGNUM *t1, BIGNUM *g,
-                          BIGNUM *u1, BIGNUM *pub_key, BIGNUM *u2, BIGNUM *p,
-                          BN_CTX *ctx, BN_MONT_CTX *mont)
+cryptodev_dsa_dsa_mod_exp(DSA *dsa, BIGNUM *t1, const BIGNUM *g,
+                          const BIGNUM *u1, const BIGNUM *pub_key,
+                          const BIGNUM *u2, const BIGNUM *p, BN_CTX *ctx,
+                          BN_MONT_CTX *mont)
 {
-    BIGNUM *t2, *dsag, *dsap, *dsapub_key;
+    const BIGNUM *dsag, *dsap, *dsapub_key;
+    BIGNUM *t2;
     int ret = 0;
     const DSA_METHOD *meth;
-    int (*bn_mod_exp)(DSA *, BIGNUM *, BIGNUM *, const BIGNUM *, const BIGNUM *,
+    int (*bn_mod_exp)(DSA *, BIGNUM *, const BIGNUM *, const BIGNUM *, const BIGNUM *,
                       BN_CTX *, BN_MONT_CTX *);
 
     t2 = BN_new();
@@ -1437,12 +1463,10 @@ cryptodev_dsa_dsa_mod_exp(DSA *dsa, BIGNUM *t1, BIGNUM *g,
     /* let t2 = y ^ u2 mod p */
     if (!bn_mod_exp(dsa, t2, dsapub_key, u2, dsap, ctx, mont))
         goto err;
-    /* let u1 = t1 * t2 mod p */
-    if (!BN_mod_mul(u1, t1, t2, dsap, ctx))
+    /* let t1 = t1 * t2 mod p */
+    if (!BN_mod_mul(t1, t1, t2, dsap, ctx))
         goto err;
 
-    BN_copy(t1, u1);
-
     ret = 1;
  err:
     BN_free(t2);
@@ -1453,14 +1477,14 @@ static DSA_SIG *cryptodev_dsa_do_sign(const unsigned char *dgst, int dlen,
                                       DSA *dsa)
 {
     struct crypt_kop kop;
-    BIGNUM *r = NULL, *s = NULL, *dsap = NULL, *dsaq = NULL, *dsag = NULL;
-    BIGNUM *priv_key = NULL;
+    BIGNUM *r, *s;
+    const BIGNUM *dsap = NULL, *dsaq = NULL, *dsag = NULL;
+    const BIGNUM *priv_key = NULL;
     DSA_SIG *dsasig, *dsaret = NULL;
 
     dsasig = DSA_SIG_new();
     if (dsasig == NULL)
         goto err;
-    DSA_SIG_get0(&r, &s, dsasig);
 
     memset(&kop, 0, sizeof(kop));
     kop.crk_op = CRK_DSA_SIGN;
@@ -1480,8 +1504,15 @@ static DSA_SIG *cryptodev_dsa_do_sign(const unsigned char *dgst, int dlen,
         goto err;
     kop.crk_iparams = 5;
 
+    r = BN_new();
+    if (r == NULL)
+        goto err;
+    s = BN_new();
+    if (s == NULL)
+        goto err;
     if (cryptodev_asym(&kop, BN_num_bytes(dsaq), r,
                        BN_num_bytes(dsaq), s) == 0) {
+        DSA_SIG_set0(dsasig, r, s);
         dsaret = dsasig;
     } else {
         dsaret = DSA_meth_get_sign(DSA_OpenSSL())(dgst, dlen, dsa);
@@ -1500,7 +1531,7 @@ cryptodev_dsa_verify(const unsigned char *dgst, int dlen,
 {
     struct crypt_kop kop;
     int dsaret = 1;
-    BIGNUM *pr, *ps, *p = NULL, *q = NULL, *g = NULL, *pub_key = NULL;
+    const BIGNUM *pr, *ps, *p = NULL, *q = NULL, *g = NULL, *pub_key = NULL;
 
     memset(&kop, 0, sizeof(kop));
     kop.crk_op = CRK_DSA_VERIFY;
@@ -1518,7 +1549,7 @@ cryptodev_dsa_verify(const unsigned char *dgst, int dlen,
     DSA_get0_key(dsa, &pub_key, NULL);
     if (bn2crparam(pub_key, &kop.crk_param[4]))
         goto err;
-    DSA_SIG_get0(&pr, &ps, sig);
+    DSA_SIG_get0(sig, &pr, &ps);
     if (bn2crparam(pr, &kop.crk_param[5]))
         goto err;
     if (bn2crparam(ps, &kop.crk_param[6]))
@@ -1556,8 +1587,8 @@ cryptodev_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
     struct crypt_kop kop;
     int dhret = 1;
     int fd, keylen;
-    BIGNUM *p = NULL;
-    BIGNUM *priv_key = NULL;
+    const BIGNUM *p = NULL;
+    const BIGNUM *priv_key = NULL;
 
     if ((fd = get_asym_dev_crypto()) < 0) {
         const DH_METHOD *meth = DH_OpenSSL();
@@ -1597,8 +1628,6 @@ cryptodev_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
     return (dhret);
 }
 
-static DH_METHOD *cryptodev_dh;
-
 #endif /* ndef OPENSSL_NO_DH */
 
 /*
@@ -1671,6 +1700,9 @@ void engine_load_cryptodev_int(void)
                                          cryptodev_rsa_nocrt_mod_exp);
             }
         }
+    } else {
+        ENGINE_free(engine);
+        return;
     }
 
 #ifndef OPENSSL_NO_DSA
@@ -1708,6 +1740,9 @@ void engine_load_cryptodev_int(void)
                                             cryptodev_dh_compute_key);
             }
         }
+    } else {
+        ENGINE_free(engine);
+        return;
     }
 #endif