Don't use CRYPTO_AES_CTR if it isn't defined.
[openssl.git] / crypto / engine / eng_cryptodev.c
index 52f4ca39019851b33d58e6201f0438d559aeb223..568e13161547f8af5e879891b08ff5b18c754860 100644 (file)
@@ -55,10 +55,10 @@ ENGINE_load_cryptodev(void)
  
 #include <sys/types.h>
 #include <crypto/cryptodev.h>
-#include <crypto/dh/dh.h>
-#include <crypto/dsa/dsa.h>
-#include <crypto/err/err.h>
-#include <crypto/rsa/rsa.h>
+#include <openssl/dh.h>
+#include <openssl/dsa.h>
+#include <openssl/err.h>
+#include <openssl/rsa.h>
 #include <sys/ioctl.h>
 #include <errno.h>
 #include <stdio.h>
@@ -79,8 +79,6 @@ struct dev_crypto_state {
        unsigned char digest_res[HASH_MAX_LEN];
        char *mac_data;
        int mac_len;
-
-       int copy;
 #endif
 };
 
@@ -149,6 +147,11 @@ static struct {
        { CRYPTO_AES_CBC,               NID_aes_128_cbc,        16,     16, },
        { CRYPTO_AES_CBC,               NID_aes_192_cbc,        16,     24, },
        { CRYPTO_AES_CBC,               NID_aes_256_cbc,        16,     32, },
+#ifdef CRYPTO_AES_CTR
+       { CRYPTO_AES_CTR,               NID_aes_128_ctr,        14,     16, },
+       { CRYPTO_AES_CTR,               NID_aes_192_ctr,        14,     24, },
+       { CRYPTO_AES_CTR,               NID_aes_256_ctr,        14,     32, },
+#endif
        { CRYPTO_BLF_CBC,               NID_bf_cbc,             8,      16, },
        { CRYPTO_CAST_CBC,              NID_cast5_cbc,          8,      16, },
        { CRYPTO_SKIPJACK_CBC,          NID_undef,              0,       0, },
@@ -200,6 +203,7 @@ get_dev_crypto(void)
 
        if ((fd = open_dev_crypto()) == -1)
                return (-1);
+#ifndef CRIOGET_NOT_NEEDED
        if (ioctl(fd, CRIOGET, &retfd) == -1)
                return (-1);
 
@@ -208,9 +212,19 @@ get_dev_crypto(void)
                close(retfd);
                return (-1);
        }
+#else
+        retfd = fd;
+#endif
        return (retfd);
 }
 
+static void put_dev_crypto(int fd)
+{
+#ifndef CRIOGET_NOT_NEEDED
+       close(fd);
+#endif
+}
+
 /* Caching version for asym operations */
 static int
 get_asym_dev_crypto(void)
@@ -252,7 +266,7 @@ get_cryptodev_ciphers(const int **cnids)
                    ioctl(fd, CIOCFSESSION, &sess.ses) != -1)
                        nids[count++] = ciphers[i].nid;
        }
-       close(fd);
+       put_dev_crypto(fd);
 
        if (count > 0)
                *cnids = nids;
@@ -291,7 +305,7 @@ get_cryptodev_digests(const int **cnids)
                    ioctl(fd, CIOCFSESSION, &sess.ses) != -1)
                        nids[count++] = digests[i].nid;
        }
-       close(fd);
+       put_dev_crypto(fd);
 
        if (count > 0)
                *cnids = nids;
@@ -436,7 +450,7 @@ cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
        sess->cipher = cipher;
 
        if (ioctl(state->d_fd, CIOCGSESSION, sess) == -1) {
-               close(state->d_fd);
+               put_dev_crypto(state->d_fd);
                state->d_fd = -1;
                return (0);
        }
@@ -473,7 +487,7 @@ cryptodev_cleanup(EVP_CIPHER_CTX *ctx)
        } else {
                ret = 1;
        }
-       close(state->d_fd);
+       put_dev_crypto(state->d_fd);
        state->d_fd = -1;
 
        return (ret);
@@ -590,7 +604,46 @@ const EVP_CIPHER cryptodev_aes_256_cbc = {
        EVP_CIPHER_get_asn1_iv,
        NULL
 };
+#ifdef CRYPTO_AES_CTR
+const EVP_CIPHER cryptodev_aes_ctr = {
+       NID_aes_128_ctr,
+       16, 16, 14,
+       EVP_CIPH_CTR_MODE,
+       cryptodev_init_key,
+       cryptodev_cipher,
+       cryptodev_cleanup,
+       sizeof(struct dev_crypto_state),
+       EVP_CIPHER_set_asn1_iv,
+       EVP_CIPHER_get_asn1_iv,
+       NULL
+};
 
+const EVP_CIPHER cryptodev_aes_ctr_192 = {
+       NID_aes_192_ctr,
+       16, 24, 14,
+       EVP_CIPH_CTR_MODE,
+       cryptodev_init_key,
+       cryptodev_cipher,
+       cryptodev_cleanup,
+       sizeof(struct dev_crypto_state),
+       EVP_CIPHER_set_asn1_iv,
+       EVP_CIPHER_get_asn1_iv,
+       NULL
+};
+
+const EVP_CIPHER cryptodev_aes_ctr_256 = {
+       NID_aes_256_ctr,
+       16, 32, 14,
+       EVP_CIPH_CTR_MODE,
+       cryptodev_init_key,
+       cryptodev_cipher,
+       cryptodev_cleanup,
+       sizeof(struct dev_crypto_state),
+       EVP_CIPHER_set_asn1_iv,
+       EVP_CIPHER_get_asn1_iv,
+       NULL
+};
+#endif
 /*
  * Registered by the ENGINE when used to find out how to deal with
  * a particular NID in the ENGINE. this says what we'll do at the
@@ -628,6 +681,17 @@ cryptodev_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
        case NID_aes_256_cbc:
                *cipher = &cryptodev_aes_256_cbc;
                break;
+#ifdef CRYPTO_AES_CTR
+       case NID_aes_128_ctr:
+               *cipher = &cryptodev_aes_ctr;
+               break;
+       case NID_aes_192_ctr:
+               *cipher = &cryptodev_aes_ctr_192;
+               break;
+       case NID_aes_256_ctr:
+               *cipher = &cryptodev_aes_ctr_256;
+               break;
+#endif
        default:
                *cipher = NULL;
                break;
@@ -686,7 +750,7 @@ static int cryptodev_digest_init(EVP_MD_CTX *ctx)
        sess->mac = digest;
 
        if (ioctl(state->d_fd, CIOCGSESSION, sess) < 0) {
-               close(state->d_fd);
+               put_dev_crypto(state->d_fd);
                state->d_fd = -1;
                printf("cryptodev_digest_init: Open session failed\n");
                return (0);
@@ -758,14 +822,12 @@ static int cryptodev_digest_final(EVP_MD_CTX *ctx, unsigned char *md)
        if (! (ctx->flags & EVP_MD_CTX_FLAG_ONESHOT) ) {
                /* if application doesn't support one buffer */
                memset(&cryp, 0, sizeof(cryp));
-
                cryp.ses = sess->ses;
                cryp.flags = 0;
                cryp.len = state->mac_len;
                cryp.src = state->mac_data;
                cryp.dst = NULL;
                cryp.mac = (caddr_t)md;
-
                if (ioctl(state->d_fd, CIOCCRYPT, &cryp) < 0) {
                        printf("cryptodev_digest_final: digest failed\n");
                        return (0);
@@ -786,6 +848,9 @@ static int cryptodev_digest_cleanup(EVP_MD_CTX *ctx)
        struct dev_crypto_state *state = ctx->md_data;
        struct session_op *sess = &state->d_sess;
 
+       if (state == NULL)
+         return 0;
+
        if (state->d_fd < 0) {
                printf("cryptodev_digest_cleanup: illegal input\n");
                return (0);
@@ -797,16 +862,13 @@ static int cryptodev_digest_cleanup(EVP_MD_CTX *ctx)
                state->mac_len = 0;
        }
 
-       if (state->copy)
-               return 1;
-
        if (ioctl(state->d_fd, CIOCFSESSION, &sess->ses) < 0) {
                printf("cryptodev_digest_cleanup: failed to close session\n");
                ret = 0;
        } else {
                ret = 1;
        }
-       close(state->d_fd);     
+       put_dev_crypto(state->d_fd);    
        state->d_fd = -1;
 
        return (ret);
@@ -816,15 +878,39 @@ static int cryptodev_digest_copy(EVP_MD_CTX *to,const EVP_MD_CTX *from)
 {
        struct dev_crypto_state *fstate = from->md_data;
        struct dev_crypto_state *dstate = to->md_data;
+       struct session_op *sess;
+       int digest;
 
-       memcpy(dstate, fstate, sizeof(struct dev_crypto_state));
+       if (dstate == NULL || fstate == NULL)
+         return 1;
 
-       if (fstate->mac_len != 0) {
-               dstate->mac_data = OPENSSL_malloc(fstate->mac_len);
-               memcpy(dstate->mac_data, fstate->mac_data, fstate->mac_len);
+               memcpy(dstate, fstate, sizeof(struct dev_crypto_state));
+
+       sess = &dstate->d_sess;
+
+       digest = digest_nid_to_cryptodev(to->digest->type);
+
+       sess->mackey = dstate->dummy_mac_key;
+       sess->mackeylen = digest_key_length(to->digest->type);
+       sess->mac = digest;
+
+       dstate->d_fd = get_dev_crypto();
+
+       if (ioctl(dstate->d_fd, CIOCGSESSION, sess) < 0) {
+               put_dev_crypto(dstate->d_fd);
+               dstate->d_fd = -1;
+               printf("cryptodev_digest_init: Open session failed\n");
+               return (0);
        }
 
-       dstate->copy = 1;
+       if (fstate->mac_len != 0) {
+               if (fstate->mac_data != NULL)
+                       {
+                       dstate->mac_data = OPENSSL_malloc(fstate->mac_len);
+                       memcpy(dstate->mac_data, fstate->mac_data, fstate->mac_len);
+                       dstate->mac_len = fstate->mac_len;
+                       }
+       }
 
        return 1;
 }
@@ -1347,11 +1433,11 @@ ENGINE_load_cryptodev(void)
         * find out what asymmetric crypto algorithms we support
         */
        if (ioctl(fd, CIOCASYMFEAT, &cryptodev_asymfeat) == -1) {
-               close(fd);
+               put_dev_crypto(fd);
                ENGINE_free(engine);
                return;
        }
-       close(fd);
+       put_dev_crypto(fd);
 
        if (!ENGINE_set_id(engine, "cryptodev") ||
            !ENGINE_set_name(engine, "BSD cryptodev engine") ||