Updated to hostap_2_6
[mech_eap.git] / libeap / src / crypto / crypto_openssl.c
index 6cff75c..19e0e2b 100644 (file)
 #include "sha1.h"
 #include "sha256.h"
 #include "sha384.h"
+#include "md5.h"
+#include "aes_wrap.h"
 #include "crypto.h"
 
+#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
+/* Compatibility wrappers for older versions. */
+
+static HMAC_CTX * HMAC_CTX_new(void)
+{
+       HMAC_CTX *ctx;
+
+       ctx = os_zalloc(sizeof(*ctx));
+       if (ctx)
+               HMAC_CTX_init(ctx);
+       return ctx;
+}
+
+
+static void HMAC_CTX_free(HMAC_CTX *ctx)
+{
+       if (!ctx)
+               return;
+       HMAC_CTX_cleanup(ctx);
+       bin_clear_free(ctx, sizeof(*ctx));
+}
+
+
+static EVP_MD_CTX * EVP_MD_CTX_new(void)
+{
+       EVP_MD_CTX *ctx;
+
+       ctx = os_zalloc(sizeof(*ctx));
+       if (ctx)
+               EVP_MD_CTX_init(ctx);
+       return ctx;
+}
+
+
+static void EVP_MD_CTX_free(EVP_MD_CTX *ctx)
+{
+       if (!ctx)
+               return;
+       EVP_MD_CTX_cleanup(ctx);
+       bin_clear_free(ctx, sizeof(*ctx));
+}
+
+#endif /* OpenSSL version < 1.1.0 */
+
 static BIGNUM * get_group5_prime(void)
 {
-#ifdef OPENSSL_IS_BORINGSSL
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
+       return BN_get_rfc3526_prime_1536(NULL);
+#elif !defined(OPENSSL_IS_BORINGSSL)
+       return get_rfc3526_prime_1536(NULL);
+#else
        static const unsigned char RFC3526_PRIME_1536[] = {
                0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
                0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
@@ -53,9 +103,7 @@ static BIGNUM * get_group5_prime(void)
                0xCA,0x23,0x73,0x27,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
        };
         return BN_bin2bn(RFC3526_PRIME_1536, sizeof(RFC3526_PRIME_1536), NULL);
-#else /* OPENSSL_IS_BORINGSSL */
-       return get_rfc3526_prime_1536(NULL);
-#endif /* OPENSSL_IS_BORINGSSL */
+#endif
 }
 
 #ifdef OPENSSL_NO_SHA256
@@ -65,29 +113,38 @@ static BIGNUM * get_group5_prime(void)
 static int openssl_digest_vector(const EVP_MD *type, size_t num_elem,
                                 const u8 *addr[], const size_t *len, u8 *mac)
 {
-       EVP_MD_CTX ctx;
+       EVP_MD_CTX *ctx;
        size_t i;
        unsigned int mac_len;
 
-       EVP_MD_CTX_init(&ctx);
-       if (!EVP_DigestInit_ex(&ctx, type, NULL)) {
+       if (TEST_FAIL())
+               return -1;
+
+       ctx = EVP_MD_CTX_new();
+       if (!ctx)
+               return -1;
+       if (!EVP_DigestInit_ex(ctx, type, NULL)) {
                wpa_printf(MSG_ERROR, "OpenSSL: EVP_DigestInit_ex failed: %s",
                           ERR_error_string(ERR_get_error(), NULL));
+               EVP_MD_CTX_free(ctx);
                return -1;
        }
        for (i = 0; i < num_elem; i++) {
-               if (!EVP_DigestUpdate(&ctx, addr[i], len[i])) {
+               if (!EVP_DigestUpdate(ctx, addr[i], len[i])) {
                        wpa_printf(MSG_ERROR, "OpenSSL: EVP_DigestUpdate "
                                   "failed: %s",
                                   ERR_error_string(ERR_get_error(), NULL));
+                       EVP_MD_CTX_free(ctx);
                        return -1;
                }
        }
-       if (!EVP_DigestFinal(&ctx, mac, &mac_len)) {
+       if (!EVP_DigestFinal(ctx, mac, &mac_len)) {
                wpa_printf(MSG_ERROR, "OpenSSL: EVP_DigestFinal failed: %s",
                           ERR_error_string(ERR_get_error(), NULL));
+               EVP_MD_CTX_free(ctx);
                return -1;
        }
+       EVP_MD_CTX_free(ctx);
 
        return 0;
 }
@@ -129,32 +186,34 @@ int rc4_skip(const u8 *key, size_t keylen, size_t skip,
 #ifdef OPENSSL_NO_RC4
        return -1;
 #else /* OPENSSL_NO_RC4 */
-       EVP_CIPHER_CTX ctx;
+       EVP_CIPHER_CTX *ctx;
        int outl;
        int res = -1;
        unsigned char skip_buf[16];
 
-       EVP_CIPHER_CTX_init(&ctx);
-       if (!EVP_CIPHER_CTX_set_padding(&ctx, 0) ||
-           !EVP_CipherInit_ex(&ctx, EVP_rc4(), NULL, NULL, NULL, 1) ||
-           !EVP_CIPHER_CTX_set_key_length(&ctx, keylen) ||
-           !EVP_CipherInit_ex(&ctx, NULL, NULL, key, NULL, 1))
+       ctx = EVP_CIPHER_CTX_new();
+       if (!ctx ||
+           !EVP_CIPHER_CTX_set_padding(ctx, 0) ||
+           !EVP_CipherInit_ex(ctx, EVP_rc4(), NULL, NULL, NULL, 1) ||
+           !EVP_CIPHER_CTX_set_key_length(ctx, keylen) ||
+           !EVP_CipherInit_ex(ctx, NULL, NULL, key, NULL, 1))
                goto out;
 
        while (skip >= sizeof(skip_buf)) {
                size_t len = skip;
                if (len > sizeof(skip_buf))
                        len = sizeof(skip_buf);
-               if (!EVP_CipherUpdate(&ctx, skip_buf, &outl, skip_buf, len))
+               if (!EVP_CipherUpdate(ctx, skip_buf, &outl, skip_buf, len))
                        goto out;
                skip -= len;
        }
 
-       if (EVP_CipherUpdate(&ctx, data, &outl, data, data_len))
+       if (EVP_CipherUpdate(ctx, data, &outl, data, data_len))
                res = 0;
 
 out:
-       EVP_CIPHER_CTX_cleanup(&ctx);
+       if (ctx)
+               EVP_CIPHER_CTX_free(ctx);
        return res;
 #endif /* OPENSSL_NO_RC4 */
 }
@@ -206,14 +265,16 @@ void * aes_encrypt_init(const u8 *key, size_t len)
        EVP_CIPHER_CTX *ctx;
        const EVP_CIPHER *type;
 
+       if (TEST_FAIL())
+               return NULL;
+
        type = aes_get_evp_cipher(len);
        if (type == NULL)
                return NULL;
 
-       ctx = os_malloc(sizeof(*ctx));
+       ctx = EVP_CIPHER_CTX_new();
        if (ctx == NULL)
                return NULL;
-       EVP_CIPHER_CTX_init(ctx);
        if (EVP_EncryptInit_ex(ctx, type, NULL, key, NULL) != 1) {
                os_free(ctx);
                return NULL;
@@ -247,8 +308,7 @@ void aes_encrypt_deinit(void *ctx)
                wpa_printf(MSG_ERROR, "OpenSSL: Unexpected padding length %d "
                           "in AES encrypt", len);
        }
-       EVP_CIPHER_CTX_cleanup(c);
-       bin_clear_free(c, sizeof(*c));
+       EVP_CIPHER_CTX_free(c);
 }
 
 
@@ -257,16 +317,18 @@ void * aes_decrypt_init(const u8 *key, size_t len)
        EVP_CIPHER_CTX *ctx;
        const EVP_CIPHER *type;
 
+       if (TEST_FAIL())
+               return NULL;
+
        type = aes_get_evp_cipher(len);
        if (type == NULL)
                return NULL;
 
-       ctx = os_malloc(sizeof(*ctx));
+       ctx = EVP_CIPHER_CTX_new();
        if (ctx == NULL)
                return NULL;
-       EVP_CIPHER_CTX_init(ctx);
        if (EVP_DecryptInit_ex(ctx, type, NULL, key, NULL) != 1) {
-               os_free(ctx);
+               EVP_CIPHER_CTX_free(ctx);
                return NULL;
        }
        EVP_CIPHER_CTX_set_padding(ctx, 0);
@@ -298,8 +360,7 @@ void aes_decrypt_deinit(void *ctx)
                wpa_printf(MSG_ERROR, "OpenSSL: Unexpected padding length %d "
                           "in AES decrypt", len);
        }
-       EVP_CIPHER_CTX_cleanup(c);
-       bin_clear_free(c, sizeof(*c));
+       EVP_CIPHER_CTX_free(c);
 }
 
 
@@ -338,51 +399,56 @@ int aes_unwrap(const u8 *kek, size_t kek_len, int n, const u8 *cipher,
 
 int aes_128_cbc_encrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len)
 {
-       EVP_CIPHER_CTX ctx;
+       EVP_CIPHER_CTX *ctx;
        int clen, len;
        u8 buf[16];
+       int res = -1;
 
-       EVP_CIPHER_CTX_init(&ctx);
-       if (EVP_EncryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, key, iv) != 1)
+       if (TEST_FAIL())
                return -1;
-       EVP_CIPHER_CTX_set_padding(&ctx, 0);
 
-       clen = data_len;
-       if (EVP_EncryptUpdate(&ctx, data, &clen, data, data_len) != 1 ||
-           clen != (int) data_len)
+       ctx = EVP_CIPHER_CTX_new();
+       if (!ctx)
                return -1;
-
+       clen = data_len;
        len = sizeof(buf);
-       if (EVP_EncryptFinal_ex(&ctx, buf, &len) != 1 || len != 0)
-               return -1;
-       EVP_CIPHER_CTX_cleanup(&ctx);
+       if (EVP_EncryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv) == 1 &&
+           EVP_CIPHER_CTX_set_padding(ctx, 0) == 1 &&
+           EVP_EncryptUpdate(ctx, data, &clen, data, data_len) == 1 &&
+           clen == (int) data_len &&
+           EVP_EncryptFinal_ex(ctx, buf, &len) == 1 && len == 0)
+               res = 0;
+       EVP_CIPHER_CTX_free(ctx);
 
-       return 0;
+       return res;
 }
 
 
 int aes_128_cbc_decrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len)
 {
-       EVP_CIPHER_CTX ctx;
+       EVP_CIPHER_CTX *ctx;
        int plen, len;
        u8 buf[16];
+       int res = -1;
 
-       EVP_CIPHER_CTX_init(&ctx);
-       if (EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, key, iv) != 1)
+       if (TEST_FAIL())
                return -1;
-       EVP_CIPHER_CTX_set_padding(&ctx, 0);
 
-       plen = data_len;
-       if (EVP_DecryptUpdate(&ctx, data, &plen, data, data_len) != 1 ||
-           plen != (int) data_len)
+       ctx = EVP_CIPHER_CTX_new();
+       if (!ctx)
                return -1;
-
+       plen = data_len;
        len = sizeof(buf);
-       if (EVP_DecryptFinal_ex(&ctx, buf, &len) != 1 || len != 0)
-               return -1;
-       EVP_CIPHER_CTX_cleanup(&ctx);
+       if (EVP_DecryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv) == 1 &&
+           EVP_CIPHER_CTX_set_padding(ctx, 0) == 1 &&
+           EVP_DecryptUpdate(ctx, data, &plen, data, data_len) == 1 &&
+           plen == (int) data_len &&
+           EVP_DecryptFinal_ex(ctx, buf, &len) == 1 && len == 0)
+               res = 0;
+       EVP_CIPHER_CTX_free(ctx);
+
+       return res;
 
-       return 0;
 }
 
 
@@ -425,8 +491,8 @@ error:
 
 
 struct crypto_cipher {
-       EVP_CIPHER_CTX enc;
-       EVP_CIPHER_CTX dec;
+       EVP_CIPHER_CTX *enc;
+       EVP_CIPHER_CTX *dec;
 };
 
 
@@ -487,23 +553,25 @@ struct crypto_cipher * crypto_cipher_init(enum crypto_cipher_alg alg,
                return NULL;
        }
 
-       EVP_CIPHER_CTX_init(&ctx->enc);
-       EVP_CIPHER_CTX_set_padding(&ctx->enc, 0);
-       if (!EVP_EncryptInit_ex(&ctx->enc, cipher, NULL, NULL, NULL) ||
-           !EVP_CIPHER_CTX_set_key_length(&ctx->enc, key_len) ||
-           !EVP_EncryptInit_ex(&ctx->enc, NULL, NULL, key, iv)) {
-               EVP_CIPHER_CTX_cleanup(&ctx->enc);
+       if (!(ctx->enc = EVP_CIPHER_CTX_new()) ||
+           !EVP_CIPHER_CTX_set_padding(ctx->enc, 0) ||
+           !EVP_EncryptInit_ex(ctx->enc, cipher, NULL, NULL, NULL) ||
+           !EVP_CIPHER_CTX_set_key_length(ctx->enc, key_len) ||
+           !EVP_EncryptInit_ex(ctx->enc, NULL, NULL, key, iv)) {
+               if (ctx->enc)
+                       EVP_CIPHER_CTX_free(ctx->enc);
                os_free(ctx);
                return NULL;
        }
 
-       EVP_CIPHER_CTX_init(&ctx->dec);
-       EVP_CIPHER_CTX_set_padding(&ctx->dec, 0);
-       if (!EVP_DecryptInit_ex(&ctx->dec, cipher, NULL, NULL, NULL) ||
-           !EVP_CIPHER_CTX_set_key_length(&ctx->dec, key_len) ||
-           !EVP_DecryptInit_ex(&ctx->dec, NULL, NULL, key, iv)) {
-               EVP_CIPHER_CTX_cleanup(&ctx->enc);
-               EVP_CIPHER_CTX_cleanup(&ctx->dec);
+       if (!(ctx->dec = EVP_CIPHER_CTX_new()) ||
+           !EVP_CIPHER_CTX_set_padding(ctx->dec, 0) ||
+           !EVP_DecryptInit_ex(ctx->dec, cipher, NULL, NULL, NULL) ||
+           !EVP_CIPHER_CTX_set_key_length(ctx->dec, key_len) ||
+           !EVP_DecryptInit_ex(ctx->dec, NULL, NULL, key, iv)) {
+               EVP_CIPHER_CTX_free(ctx->enc);
+               if (ctx->dec)
+                       EVP_CIPHER_CTX_free(ctx->dec);
                os_free(ctx);
                return NULL;
        }
@@ -516,7 +584,7 @@ int crypto_cipher_encrypt(struct crypto_cipher *ctx, const u8 *plain,
                          u8 *crypt, size_t len)
 {
        int outl;
-       if (!EVP_EncryptUpdate(&ctx->enc, crypt, &outl, plain, len))
+       if (!EVP_EncryptUpdate(ctx->enc, crypt, &outl, plain, len))
                return -1;
        return 0;
 }
@@ -527,7 +595,7 @@ int crypto_cipher_decrypt(struct crypto_cipher *ctx, const u8 *crypt,
 {
        int outl;
        outl = len;
-       if (!EVP_DecryptUpdate(&ctx->dec, plain, &outl, crypt, len))
+       if (!EVP_DecryptUpdate(ctx->dec, plain, &outl, crypt, len))
                return -1;
        return 0;
 }
@@ -535,19 +603,21 @@ int crypto_cipher_decrypt(struct crypto_cipher *ctx, const u8 *crypt,
 
 void crypto_cipher_deinit(struct crypto_cipher *ctx)
 {
-       EVP_CIPHER_CTX_cleanup(&ctx->enc);
-       EVP_CIPHER_CTX_cleanup(&ctx->dec);
+       EVP_CIPHER_CTX_free(ctx->enc);
+       EVP_CIPHER_CTX_free(ctx->dec);
        os_free(ctx);
 }
 
 
 void * dh5_init(struct wpabuf **priv, struct wpabuf **publ)
 {
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
        DH *dh;
        struct wpabuf *pubkey = NULL, *privkey = NULL;
        size_t publen, privlen;
 
        *priv = NULL;
+       wpabuf_free(*publ);
        *publ = NULL;
 
        dh = DH_new();
@@ -586,11 +656,63 @@ err:
        wpabuf_clear_free(privkey);
        DH_free(dh);
        return NULL;
+#else
+       DH *dh;
+       struct wpabuf *pubkey = NULL, *privkey = NULL;
+       size_t publen, privlen;
+       BIGNUM *p = NULL, *g;
+       const BIGNUM *priv_key = NULL, *pub_key = NULL;
+
+       *priv = NULL;
+       wpabuf_free(*publ);
+       *publ = NULL;
+
+       dh = DH_new();
+       if (dh == NULL)
+               return NULL;
+
+       g = BN_new();
+       p = get_group5_prime();
+       if (!g || BN_set_word(g, 2) != 1 || !p ||
+           DH_set0_pqg(dh, p, NULL, g) != 1)
+               goto err;
+       p = NULL;
+       g = NULL;
+
+       if (DH_generate_key(dh) != 1)
+               goto err;
+
+       DH_get0_key(dh, &pub_key, &priv_key);
+       publen = BN_num_bytes(pub_key);
+       pubkey = wpabuf_alloc(publen);
+       if (!pubkey)
+               goto err;
+       privlen = BN_num_bytes(priv_key);
+       privkey = wpabuf_alloc(privlen);
+       if (!privkey)
+               goto err;
+
+       BN_bn2bin(pub_key, wpabuf_put(pubkey, publen));
+       BN_bn2bin(priv_key, wpabuf_put(privkey, privlen));
+
+       *priv = privkey;
+       *publ = pubkey;
+       return dh;
+
+err:
+       BN_free(p);
+       BN_free(g);
+       wpabuf_clear_free(pubkey);
+       wpabuf_clear_free(privkey);
+       DH_free(dh);
+       return NULL;
+#endif
 }
 
 
 void * dh5_init_fixed(const struct wpabuf *priv, const struct wpabuf *publ)
 {
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
        DH *dh;
 
        dh = DH_new();
@@ -621,6 +743,42 @@ void * dh5_init_fixed(const struct wpabuf *priv, const struct wpabuf *publ)
 err:
        DH_free(dh);
        return NULL;
+#else
+       DH *dh;
+       BIGNUM *p = NULL, *g, *priv_key = NULL, *pub_key = NULL;
+
+       dh = DH_new();
+       if (dh == NULL)
+               return NULL;
+
+       g = BN_new();
+       p = get_group5_prime();
+       if (!g || BN_set_word(g, 2) != 1 || !p ||
+           DH_set0_pqg(dh, p, NULL, g) != 1)
+               goto err;
+       p = NULL;
+       g = NULL;
+
+       priv_key = BN_bin2bn(wpabuf_head(priv), wpabuf_len(priv), NULL);
+       pub_key = BN_bin2bn(wpabuf_head(publ), wpabuf_len(publ), NULL);
+       if (!priv_key || !pub_key || DH_set0_key(dh, pub_key, priv_key) != 1)
+               goto err;
+       pub_key = NULL;
+       priv_key = NULL;
+
+       if (DH_generate_key(dh) != 1)
+               goto err;
+
+       return dh;
+
+err:
+       BN_free(p);
+       BN_free(g);
+       BN_free(pub_key);
+       BN_clear_free(priv_key);
+       DH_free(dh);
+       return NULL;
+#endif
 }
 
 
@@ -672,7 +830,7 @@ void dh5_free(void *ctx)
 
 
 struct crypto_hash {
-       HMAC_CTX ctx;
+       HMAC_CTX *ctx;
 };
 
 
@@ -707,16 +865,17 @@ struct crypto_hash * crypto_hash_init(enum crypto_hash_alg alg, const u8 *key,
        ctx = os_zalloc(sizeof(*ctx));
        if (ctx == NULL)
                return NULL;
-       HMAC_CTX_init(&ctx->ctx);
+       ctx->ctx = HMAC_CTX_new();
+       if (!ctx->ctx) {
+               os_free(ctx);
+               return NULL;
+       }
 
-#if OPENSSL_VERSION_NUMBER < 0x00909000
-       HMAC_Init_ex(&ctx->ctx, key, key_len, md, NULL);
-#else /* openssl < 0.9.9 */
-       if (HMAC_Init_ex(&ctx->ctx, key, key_len, md, NULL) != 1) {
+       if (HMAC_Init_ex(ctx->ctx, key, key_len, md, NULL) != 1) {
+               HMAC_CTX_free(ctx->ctx);
                bin_clear_free(ctx, sizeof(*ctx));
                return NULL;
        }
-#endif /* openssl < 0.9.9 */
 
        return ctx;
 }
@@ -726,7 +885,7 @@ void crypto_hash_update(struct crypto_hash *ctx, const u8 *data, size_t len)
 {
        if (ctx == NULL)
                return;
-       HMAC_Update(&ctx->ctx, data, len);
+       HMAC_Update(ctx->ctx, data, len);
 }
 
 
@@ -739,18 +898,14 @@ int crypto_hash_finish(struct crypto_hash *ctx, u8 *mac, size_t *len)
                return -2;
 
        if (mac == NULL || len == NULL) {
+               HMAC_CTX_free(ctx->ctx);
                bin_clear_free(ctx, sizeof(*ctx));
                return 0;
        }
 
        mdlen = *len;
-#if OPENSSL_VERSION_NUMBER < 0x00909000
-       HMAC_Final(&ctx->ctx, mac, &mdlen);
-       res = 1;
-#else /* openssl < 0.9.9 */
-       res = HMAC_Final(&ctx->ctx, mac, &mdlen);
-#endif /* openssl < 0.9.9 */
-       HMAC_CTX_cleanup(&ctx->ctx);
+       res = HMAC_Final(ctx->ctx, mac, &mdlen);
+       HMAC_CTX_free(ctx->ctx);
        bin_clear_free(ctx, sizeof(*ctx));
 
        if (res == 1) {
@@ -767,28 +922,26 @@ static int openssl_hmac_vector(const EVP_MD *type, const u8 *key,
                               const u8 *addr[], const size_t *len, u8 *mac,
                               unsigned int mdlen)
 {
-       HMAC_CTX ctx;
+       HMAC_CTX *ctx;
        size_t i;
        int res;
 
-       HMAC_CTX_init(&ctx);
-#if OPENSSL_VERSION_NUMBER < 0x00909000
-       HMAC_Init_ex(&ctx, key, key_len, type, NULL);
-#else /* openssl < 0.9.9 */
-       if (HMAC_Init_ex(&ctx, key, key_len, type, NULL) != 1)
+       if (TEST_FAIL())
                return -1;
-#endif /* openssl < 0.9.9 */
+
+       ctx = HMAC_CTX_new();
+       if (!ctx)
+               return -1;
+       res = HMAC_Init_ex(ctx, key, key_len, type, NULL);
+       if (res != 1)
+               goto done;
 
        for (i = 0; i < num_elem; i++)
-               HMAC_Update(&ctx, addr[i], len[i]);
+               HMAC_Update(ctx, addr[i], len[i]);
 
-#if OPENSSL_VERSION_NUMBER < 0x00909000
-       HMAC_Final(&ctx, mac, &mdlen);
-       res = 1;
-#else /* openssl < 0.9.9 */
-       res = HMAC_Final(&ctx, mac, &mdlen);
-#endif /* openssl < 0.9.9 */
-       HMAC_CTX_cleanup(&ctx);
+       res = HMAC_Final(ctx, mac, &mdlen);
+done:
+       HMAC_CTX_free(ctx);
 
        return res == 1 ? 0 : -1;
 }
@@ -892,6 +1045,9 @@ int omac1_aes_vector(const u8 *key, size_t key_len, size_t num_elem,
        int ret = -1;
        size_t outlen, i;
 
+       if (TEST_FAIL())
+               return -1;
+
        ctx = CMAC_CTX_new();
        if (ctx == NULL)
                return -1;
@@ -941,13 +1097,20 @@ int omac1_aes_256(const u8 *key, const u8 *data, size_t data_len, u8 *mac)
 
 struct crypto_bignum * crypto_bignum_init(void)
 {
+       if (TEST_FAIL())
+               return NULL;
        return (struct crypto_bignum *) BN_new();
 }
 
 
 struct crypto_bignum * crypto_bignum_init_set(const u8 *buf, size_t len)
 {
-       BIGNUM *bn = BN_bin2bn(buf, len, NULL);
+       BIGNUM *bn;
+
+       if (TEST_FAIL())
+               return NULL;
+
+       bn = BN_bin2bn(buf, len, NULL);
        return (struct crypto_bignum *) bn;
 }
 
@@ -966,6 +1129,9 @@ int crypto_bignum_to_bin(const struct crypto_bignum *a,
 {
        int num_bytes, offset;
 
+       if (TEST_FAIL())
+               return -1;
+
        if (padlen > buflen)
                return -1;
 
@@ -1019,6 +1185,9 @@ int crypto_bignum_exptmod(const struct crypto_bignum *a,
        int res;
        BN_CTX *bnctx;
 
+       if (TEST_FAIL())
+               return -1;
+
        bnctx = BN_CTX_new();
        if (bnctx == NULL)
                return -1;
@@ -1037,6 +1206,8 @@ int crypto_bignum_inverse(const struct crypto_bignum *a,
        BIGNUM *res;
        BN_CTX *bnctx;
 
+       if (TEST_FAIL())
+               return -1;
        bnctx = BN_CTX_new();
        if (bnctx == NULL)
                return -1;
@@ -1052,6 +1223,8 @@ int crypto_bignum_sub(const struct crypto_bignum *a,
                      const struct crypto_bignum *b,
                      struct crypto_bignum *c)
 {
+       if (TEST_FAIL())
+               return -1;
        return BN_sub((BIGNUM *) c, (const BIGNUM *) a, (const BIGNUM *) b) ?
                0 : -1;
 }
@@ -1065,6 +1238,9 @@ int crypto_bignum_div(const struct crypto_bignum *a,
 
        BN_CTX *bnctx;
 
+       if (TEST_FAIL())
+               return -1;
+
        bnctx = BN_CTX_new();
        if (bnctx == NULL)
                return -1;
@@ -1085,6 +1261,9 @@ int crypto_bignum_mulmod(const struct crypto_bignum *a,
 
        BN_CTX *bnctx;
 
+       if (TEST_FAIL())
+               return -1;
+
        bnctx = BN_CTX_new();
        if (bnctx == NULL)
                return -1;
@@ -1128,6 +1307,9 @@ int crypto_bignum_legendre(const struct crypto_bignum *a,
        BIGNUM *exp = NULL, *tmp = NULL;
        int res = -2;
 
+       if (TEST_FAIL())
+               return -2;
+
        bnctx = BN_CTX_new();
        if (bnctx == NULL)
                return -2;
@@ -1252,6 +1434,8 @@ void crypto_ec_deinit(struct crypto_ec *e)
 
 struct crypto_ec_point * crypto_ec_point_init(struct crypto_ec *e)
 {
+       if (TEST_FAIL())
+               return NULL;
        if (e == NULL)
                return NULL;
        return (struct crypto_ec_point *) EC_POINT_new(e->group);
@@ -1298,6 +1482,9 @@ int crypto_ec_point_to_bin(struct crypto_ec *e,
        int ret = -1;
        int len = BN_num_bytes(e->prime);
 
+       if (TEST_FAIL())
+               return -1;
+
        x_bn = BN_new();
        y_bn = BN_new();
 
@@ -1328,6 +1515,9 @@ struct crypto_ec_point * crypto_ec_point_from_bin(struct crypto_ec *e,
        EC_POINT *elem;
        int len = BN_num_bytes(e->prime);
 
+       if (TEST_FAIL())
+               return NULL;
+
        x = BN_bin2bn(val, len, NULL);
        y = BN_bin2bn(val + len, len, NULL);
        elem = EC_POINT_new(e->group);
@@ -1355,6 +1545,8 @@ int crypto_ec_point_add(struct crypto_ec *e, const struct crypto_ec_point *a,
                        const struct crypto_ec_point *b,
                        struct crypto_ec_point *c)
 {
+       if (TEST_FAIL())
+               return -1;
        return EC_POINT_add(e->group, (EC_POINT *) c, (const EC_POINT *) a,
                            (const EC_POINT *) b, e->bnctx) ? 0 : -1;
 }
@@ -1364,6 +1556,8 @@ int crypto_ec_point_mul(struct crypto_ec *e, const struct crypto_ec_point *p,
                        const struct crypto_bignum *b,
                        struct crypto_ec_point *res)
 {
+       if (TEST_FAIL())
+               return -1;
        return EC_POINT_mul(e->group, (EC_POINT *) res, NULL,
                            (const EC_POINT *) p, (const BIGNUM *) b, e->bnctx)
                ? 0 : -1;
@@ -1372,6 +1566,8 @@ int crypto_ec_point_mul(struct crypto_ec *e, const struct crypto_ec_point *p,
 
 int crypto_ec_point_invert(struct crypto_ec *e, struct crypto_ec_point *p)
 {
+       if (TEST_FAIL())
+               return -1;
        return EC_POINT_invert(e->group, (EC_POINT *) p, e->bnctx) ? 0 : -1;
 }
 
@@ -1380,6 +1576,8 @@ int crypto_ec_point_solve_y_coord(struct crypto_ec *e,
                                  struct crypto_ec_point *p,
                                  const struct crypto_bignum *x, int y_bit)
 {
+       if (TEST_FAIL())
+               return -1;
        if (!EC_POINT_set_compressed_coordinates_GFp(e->group, (EC_POINT *) p,
                                                     (const BIGNUM *) x, y_bit,
                                                     e->bnctx) ||
@@ -1395,6 +1593,9 @@ crypto_ec_point_compute_y_sqr(struct crypto_ec *e,
 {
        BIGNUM *tmp, *tmp2, *y_sqr = NULL;
 
+       if (TEST_FAIL())
+               return NULL;
+
        tmp = BN_new();
        tmp2 = BN_new();