]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
EAP-pwd: Replace direct OpenSSL HMAC use with wrapper
authorJouni Malinen <j@w1.fi>
Mon, 2 Jul 2012 19:10:03 +0000 (22:10 +0300)
committerJouni Malinen <j@w1.fi>
Mon, 2 Jul 2012 19:10:03 +0000 (22:10 +0300)
This is a step towards allowing EAP-pwd to be supported with other
crypto libraries.

Signed-hostap: Jouni Malinen <j@w1.fi>

src/eap_common/eap_pwd_common.c
src/eap_common/eap_pwd_common.h
src/eap_peer/eap_pwd.c
src/eap_server/eap_server_pwd.c

index c32f9fb93012150bb8d0e2a73b1b0a89d6fc7884..7d6e6b8898a1694b93555a2567f6ef7387c1cfd8 100644 (file)
@@ -8,70 +8,76 @@
 
 #include "includes.h"
 #include "common.h"
+#include "crypto/sha256.h"
+#include "crypto/crypto.h"
 #include "eap_defs.h"
 #include "eap_pwd_common.h"
 
 /* The random function H(x) = HMAC-SHA256(0^32, x) */
-void H_Init(HMAC_CTX *ctx)
+struct crypto_hash * eap_pwd_h_init(void)
 {
-       u8 allzero[SHA256_DIGEST_LENGTH];
-
-       os_memset(allzero, 0, SHA256_DIGEST_LENGTH);
-       HMAC_Init(ctx, allzero, SHA256_DIGEST_LENGTH, EVP_sha256());
+       u8 allzero[SHA256_MAC_LEN];
+       os_memset(allzero, 0, SHA256_MAC_LEN);
+       return crypto_hash_init(CRYPTO_HASH_ALG_HMAC_SHA256, allzero,
+                               SHA256_MAC_LEN);
 }
 
 
-void H_Update(HMAC_CTX *ctx, const u8 *data, int len)
+void eap_pwd_h_update(struct crypto_hash *hash, const u8 *data, size_t len)
 {
-       HMAC_Update(ctx, data, len);
+       crypto_hash_update(hash, data, len);
 }
 
 
-void H_Final(HMAC_CTX *ctx, u8 *digest)
+void eap_pwd_h_final(struct crypto_hash *hash, u8 *digest)
 {
-       unsigned int mdlen = SHA256_DIGEST_LENGTH;
-
-       HMAC_Final(ctx, digest, &mdlen);
-       HMAC_CTX_cleanup(ctx);
+       size_t len = SHA256_MAC_LEN;
+       crypto_hash_finish(hash, digest, &len);
 }
 
 
 /* a counter-based KDF based on NIST SP800-108 */
-void eap_pwd_kdf(u8 *key, int keylen, u8 *label, int labellen,
-                u8 *result, int resultbitlen)
+static int eap_pwd_kdf(const u8 *key, size_t keylen, const u8 *label,
+                      size_t labellen, u8 *result, size_t resultbitlen)
 {
-       HMAC_CTX hctx;
-       unsigned char digest[SHA256_DIGEST_LENGTH];
+       struct crypto_hash *hash;
+       u8 digest[SHA256_MAC_LEN];
        u16 i, ctr, L;
-       int resultbytelen, len = 0;
-       unsigned int mdlen = SHA256_DIGEST_LENGTH;
-       unsigned char mask = 0xff;
+       size_t resultbytelen, len = 0, mdlen;
 
-       resultbytelen = (resultbitlen + 7)/8;
+       resultbytelen = (resultbitlen + 7) / 8;
        ctr = 0;
        L = htons(resultbitlen);
        while (len < resultbytelen) {
-               ctr++; i = htons(ctr);
-               HMAC_Init(&hctx, key, keylen, EVP_sha256());
+               ctr++;
+               i = htons(ctr);
+               hash = crypto_hash_init(CRYPTO_HASH_ALG_HMAC_SHA256,
+                                       key, keylen);
+               if (hash == NULL)
+                       return -1;
                if (ctr > 1)
-                       HMAC_Update(&hctx, digest, mdlen);
-               HMAC_Update(&hctx, (u8 *) &i, sizeof(u16));
-               HMAC_Update(&hctx, label, labellen);
-               HMAC_Update(&hctx, (u8 *) &L, sizeof(u16));
-               HMAC_Final(&hctx, digest, &mdlen);
-               if ((len + (int) mdlen) > resultbytelen)
+                       crypto_hash_update(hash, digest, SHA256_MAC_LEN);
+               crypto_hash_update(hash, (u8 *) &i, sizeof(u16));
+               crypto_hash_update(hash, label, labellen);
+               crypto_hash_update(hash, (u8 *) &L, sizeof(u16));
+               mdlen = SHA256_MAC_LEN;
+               if (crypto_hash_finish(hash, digest, &mdlen) < 0)
+                       return -1;
+               if ((len + mdlen) > resultbytelen)
                        os_memcpy(result + len, digest, resultbytelen - len);
                else
                        os_memcpy(result + len, digest, mdlen);
                len += mdlen;
-               HMAC_CTX_cleanup(&hctx);
        }
 
        /* since we're expanding to a bit length, mask off the excess */
        if (resultbitlen % 8) {
+               u8 mask = 0xff;
                mask <<= (8 - (resultbitlen % 8));
                result[resultbytelen - 1] &= mask;
        }
+
+       return 0;
 }
 
 
@@ -85,9 +91,10 @@ int compute_password_element(EAP_PWD_group *grp, u16 num,
                             u8 *id_peer, int id_peer_len, u8 *token)
 {
        BIGNUM *x_candidate = NULL, *rnd = NULL, *cofactor = NULL;
-       HMAC_CTX ctx;
-       unsigned char pwe_digest[SHA256_DIGEST_LENGTH], *prfbuf = NULL, ctr;
-       int nid, is_odd, primebitlen, primebytelen, ret = 0;
+       struct crypto_hash *hash;
+       unsigned char pwe_digest[SHA256_MAC_LEN], *prfbuf = NULL, ctr;
+       int nid, is_odd, ret = 0;
+       size_t primebytelen, primebitlen;
 
        switch (num) { /* from IANA registry for IKE D-H groups */
         case 19:
@@ -167,20 +174,23 @@ int compute_password_element(EAP_PWD_group *grp, u16 num,
                 *    pwd-seed = H(token | peer-id | server-id | password |
                 *                 counter)
                 */
-               H_Init(&ctx);
-               H_Update(&ctx, token, sizeof(u32));
-               H_Update(&ctx, id_peer, id_peer_len);
-               H_Update(&ctx, id_server, id_server_len);
-               H_Update(&ctx, password, password_len);
-               H_Update(&ctx, &ctr, sizeof(ctr));
-               H_Final(&ctx, pwe_digest);
-
-               BN_bin2bn(pwe_digest, SHA256_DIGEST_LENGTH, rnd);
-
-               eap_pwd_kdf(pwe_digest, SHA256_DIGEST_LENGTH,
-                           (unsigned char *) "EAP-pwd Hunting And Pecking",
-                           os_strlen("EAP-pwd Hunting And Pecking"),
-                           prfbuf, primebitlen);
+               hash = eap_pwd_h_init();
+               if (hash == NULL)
+                       goto fail;
+               eap_pwd_h_update(hash, token, sizeof(u32));
+               eap_pwd_h_update(hash, id_peer, id_peer_len);
+               eap_pwd_h_update(hash, id_server, id_server_len);
+               eap_pwd_h_update(hash, password, password_len);
+               eap_pwd_h_update(hash, &ctr, sizeof(ctr));
+               eap_pwd_h_final(hash, pwe_digest);
+
+               BN_bin2bn(pwe_digest, SHA256_MAC_LEN, rnd);
+
+               if (eap_pwd_kdf(pwe_digest, SHA256_MAC_LEN,
+                               (u8 *) "EAP-pwd Hunting And Pecking",
+                               os_strlen("EAP-pwd Hunting And Pecking"),
+                               prfbuf, primebitlen) < 0)
+                       goto fail;
 
                BN_bin2bn(prfbuf, primebytelen, x_candidate);
 
@@ -276,9 +286,9 @@ int compute_keys(EAP_PWD_group *grp, BN_CTX *bnctx, BIGNUM *k,
                 u8 *confirm_peer, u8 *confirm_server,
                 u32 *ciphersuite, u8 *msk, u8 *emsk)
 {
-       HMAC_CTX ctx;
-       u8 mk[SHA256_DIGEST_LENGTH], *cruft;
-       u8 session_id[SHA256_DIGEST_LENGTH + 1];
+       struct crypto_hash *hash;
+       u8 mk[SHA256_MAC_LEN], *cruft;
+       u8 session_id[SHA256_MAC_LEN + 1];
        u8 msk_emsk[EAP_MSK_LEN + EAP_EMSK_LEN];
        int offset;
 
@@ -290,37 +300,46 @@ int compute_keys(EAP_PWD_group *grp, BN_CTX *bnctx, BIGNUM *k,
         *      scal_s)
         */
        session_id[0] = EAP_TYPE_PWD;
-       H_Init(&ctx);
-       H_Update(&ctx, (u8 *)ciphersuite, sizeof(u32));
+       hash = eap_pwd_h_init();
+       if (hash == NULL) {
+               os_free(cruft);
+               return -1;
+       }
+       eap_pwd_h_update(hash, (u8 *) ciphersuite, sizeof(u32));
        offset = BN_num_bytes(grp->order) - BN_num_bytes(peer_scalar);
        os_memset(cruft, 0, BN_num_bytes(grp->prime));
        BN_bn2bin(peer_scalar, cruft + offset);
-       H_Update(&ctx, cruft, BN_num_bytes(grp->order));
+       eap_pwd_h_update(hash, cruft, BN_num_bytes(grp->order));
        offset = BN_num_bytes(grp->order) - BN_num_bytes(server_scalar);
        os_memset(cruft, 0, BN_num_bytes(grp->prime));
        BN_bn2bin(server_scalar, cruft + offset);
-       H_Update(&ctx, cruft, BN_num_bytes(grp->order));
-       H_Final(&ctx, &session_id[1]);
+       eap_pwd_h_update(hash, cruft, BN_num_bytes(grp->order));
+       eap_pwd_h_final(hash, &session_id[1]);
 
        /* then compute MK = H(k | confirm-peer | confirm-server) */
-       H_Init(&ctx);
+       hash = eap_pwd_h_init();
+       if (hash == NULL) {
+               os_free(cruft);
+               return -1;
+       }
        offset = BN_num_bytes(grp->prime) - BN_num_bytes(k);
        os_memset(cruft, 0, BN_num_bytes(grp->prime));
        BN_bn2bin(k, cruft + offset);
-       H_Update(&ctx, cruft, BN_num_bytes(grp->prime));
-       H_Update(&ctx, confirm_peer, SHA256_DIGEST_LENGTH);
-       H_Update(&ctx, confirm_server, SHA256_DIGEST_LENGTH);
-       H_Final(&ctx, mk);
+       eap_pwd_h_update(hash, cruft, BN_num_bytes(grp->prime));
+       os_free(cruft);
+       eap_pwd_h_update(hash, confirm_peer, SHA256_MAC_LEN);
+       eap_pwd_h_update(hash, confirm_server, SHA256_MAC_LEN);
+       eap_pwd_h_final(hash, mk);
 
        /* stretch the mk with the session-id to get MSK | EMSK */
-       eap_pwd_kdf(mk, SHA256_DIGEST_LENGTH,
-                   session_id, SHA256_DIGEST_LENGTH+1,
-                   msk_emsk, (EAP_MSK_LEN + EAP_EMSK_LEN) * 8);
+       if (eap_pwd_kdf(mk, SHA256_MAC_LEN,
+                       session_id, SHA256_MAC_LEN + 1,
+                       msk_emsk, (EAP_MSK_LEN + EAP_EMSK_LEN) * 8) < 0) {
+               return -1;
+       }
 
        os_memcpy(msk, msk_emsk, EAP_MSK_LEN);
        os_memcpy(emsk, msk_emsk + EAP_MSK_LEN, EAP_EMSK_LEN);
 
-       os_free(cruft);
-
        return 1;
 }
index 358d008e8235cd1268f027244b01543a2580fa79..816e58ccb3d014de324f8413ee73fd5b82320720 100644 (file)
 #define EAP_PWD_COMMON_H
 
 #include <openssl/bn.h>
-#include <openssl/sha.h>
 #include <openssl/ec.h>
 #include <openssl/evp.h>
-#include <openssl/hmac.h>
 
 /*
  * definition of a finite cyclic group
@@ -62,8 +60,8 @@ int compute_password_element(EAP_PWD_group *, u16, u8 *, int, u8 *, int, u8 *,
                             int, u8 *);
 int compute_keys(EAP_PWD_group *, BN_CTX *, BIGNUM *, BIGNUM *, BIGNUM *,
                 u8 *, u8 *, u32 *, u8 *, u8 *);
-void H_Init(HMAC_CTX *);
-void H_Update(HMAC_CTX *, const u8 *, int);
-void H_Final(HMAC_CTX *, u8 *);
+struct crypto_hash * eap_pwd_h_init(void);
+void eap_pwd_h_update(struct crypto_hash *hash, const u8 *data, size_t len);
+void eap_pwd_h_final(struct crypto_hash *hash, u8 *digest);
 
 #endif  /* EAP_PWD_COMMON_H */
index a5caf543d86fd828c3d6b0c9394c3baf69a98b9b..267d0a5c69768d57bc096a64ea8479a83f543339 100644 (file)
@@ -9,6 +9,7 @@
 #include "includes.h"
 
 #include "common.h"
+#include "crypto/sha256.h"
 #include "eap_peer/eap_i.h"
 #include "eap_common/eap_pwd_common.h"
 
@@ -459,10 +460,10 @@ eap_pwd_perform_confirm_exchange(struct eap_sm *sm, struct eap_pwd_data *data,
                                 const u8 *payload, size_t payload_len)
 {
        BIGNUM *x = NULL, *y = NULL;
-       HMAC_CTX ctx;
+       struct crypto_hash *hash;
        u32 cs;
        u16 grp;
-       u8 conf[SHA256_DIGEST_LENGTH], *cruft = NULL, *ptr;
+       u8 conf[SHA256_MAC_LEN], *cruft = NULL, *ptr;
        int offset;
 
        /*
@@ -489,7 +490,9 @@ eap_pwd_perform_confirm_exchange(struct eap_sm *sm, struct eap_pwd_data *data,
         * server's commit is H(k | server_element | server_scalar |
         *                      peer_element | peer_scalar | ciphersuite)
         */
-       H_Init(&ctx);
+       hash = eap_pwd_h_init();
+       if (hash == NULL)
+               goto fin;
 
        /*
         * zero the memory each time because this is mod prime math and some
@@ -498,7 +501,7 @@ eap_pwd_perform_confirm_exchange(struct eap_sm *sm, struct eap_pwd_data *data,
        os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
        offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(data->k);
        BN_bn2bin(data->k, cruft + offset);
-       H_Update(&ctx, cruft, BN_num_bytes(data->grp->prime));
+       eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->prime));
 
        /* server element: x, y */
        if (!EC_POINT_get_affine_coordinates_GFp(data->grp->group,
@@ -511,18 +514,18 @@ eap_pwd_perform_confirm_exchange(struct eap_sm *sm, struct eap_pwd_data *data,
        os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
        offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(x);
        BN_bn2bin(x, cruft + offset);
-       H_Update(&ctx, cruft, BN_num_bytes(data->grp->prime));
+       eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->prime));
        os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
        offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(y);
        BN_bn2bin(y, cruft + offset);
-       H_Update(&ctx, cruft, BN_num_bytes(data->grp->prime));
+       eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->prime));
 
        /* server scalar */
        os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
        offset = BN_num_bytes(data->grp->order) -
                BN_num_bytes(data->server_scalar);
        BN_bn2bin(data->server_scalar, cruft + offset);
-       H_Update(&ctx, cruft, BN_num_bytes(data->grp->order));
+       eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->order));
 
        /* my element: x, y */
        if (!EC_POINT_get_affine_coordinates_GFp(data->grp->group,
@@ -536,27 +539,27 @@ eap_pwd_perform_confirm_exchange(struct eap_sm *sm, struct eap_pwd_data *data,
        os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
        offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(x);
        BN_bn2bin(x, cruft + offset);
-       H_Update(&ctx, cruft, BN_num_bytes(data->grp->prime));
+       eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->prime));
        os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
        offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(y);
        BN_bn2bin(y, cruft + offset);
-       H_Update(&ctx, cruft, BN_num_bytes(data->grp->prime));
+       eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->prime));
 
        /* my scalar */
        os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
        offset = BN_num_bytes(data->grp->order) -
                BN_num_bytes(data->my_scalar);
        BN_bn2bin(data->my_scalar, cruft + offset);
-       H_Update(&ctx, cruft, BN_num_bytes(data->grp->order));
+       eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->order));
 
        /* the ciphersuite */
-       H_Update(&ctx, (u8 *) &cs, sizeof(u32));
+       eap_pwd_h_update(hash, (u8 *) &cs, sizeof(u32));
 
        /* random function fin */
-       H_Final(&ctx, conf);
+       eap_pwd_h_final(hash, conf);
 
        ptr = (u8 *) payload;
-       if (os_memcmp(conf, ptr, SHA256_DIGEST_LENGTH)) {
+       if (os_memcmp(conf, ptr, SHA256_MAC_LEN)) {
                wpa_printf(MSG_INFO, "EAP-PWD (peer): confirm did not verify");
                goto fin;
        }
@@ -568,13 +571,15 @@ eap_pwd_perform_confirm_exchange(struct eap_sm *sm, struct eap_pwd_data *data,
         *  H(k | peer_element | peer_scalar | server_element | server_scalar |
         *    ciphersuite)
         */
-       H_Init(&ctx);
+       hash = eap_pwd_h_init();
+       if (hash == NULL)
+               goto fin;
 
        /* k */
        os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
        offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(data->k);
        BN_bn2bin(data->k, cruft + offset);
-       H_Update(&ctx, cruft, BN_num_bytes(data->grp->prime));
+       eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->prime));
 
        /* my element */
        if (!EC_POINT_get_affine_coordinates_GFp(data->grp->group,
@@ -587,18 +592,18 @@ eap_pwd_perform_confirm_exchange(struct eap_sm *sm, struct eap_pwd_data *data,
        os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
        offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(x);
        BN_bn2bin(x, cruft + offset);
-       H_Update(&ctx, cruft, BN_num_bytes(data->grp->prime));
+       eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->prime));
        os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
        offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(y);
        BN_bn2bin(y, cruft + offset);
-       H_Update(&ctx, cruft, BN_num_bytes(data->grp->prime));
+       eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->prime));
 
        /* my scalar */
        os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
        offset = BN_num_bytes(data->grp->order) -
                BN_num_bytes(data->my_scalar);
        BN_bn2bin(data->my_scalar, cruft + offset);
-       H_Update(&ctx, cruft, BN_num_bytes(data->grp->order));
+       eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->order));
 
        /* server element: x, y */
        if (!EC_POINT_get_affine_coordinates_GFp(data->grp->group,
@@ -611,24 +616,24 @@ eap_pwd_perform_confirm_exchange(struct eap_sm *sm, struct eap_pwd_data *data,
        os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
        offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(x);
        BN_bn2bin(x, cruft + offset);
-       H_Update(&ctx, cruft, BN_num_bytes(data->grp->prime));
+       eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->prime));
        os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
        offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(y);
        BN_bn2bin(y, cruft + offset);
-       H_Update(&ctx, cruft, BN_num_bytes(data->grp->prime));
+       eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->prime));
 
        /* server scalar */
        os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
        offset = BN_num_bytes(data->grp->order) -
                BN_num_bytes(data->server_scalar);
        BN_bn2bin(data->server_scalar, cruft + offset);
-       H_Update(&ctx, cruft, BN_num_bytes(data->grp->order));
+       eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->order));
 
        /* the ciphersuite */
-       H_Update(&ctx, (u8 *) &cs, sizeof(u32));
+       eap_pwd_h_update(hash, (u8 *) &cs, sizeof(u32));
 
        /* all done */
-       H_Final(&ctx, conf);
+       eap_pwd_h_final(hash, conf);
 
        if (compute_keys(data->grp, data->bnctx, data->k,
                         data->my_scalar, data->server_scalar, conf, ptr,
@@ -638,11 +643,11 @@ eap_pwd_perform_confirm_exchange(struct eap_sm *sm, struct eap_pwd_data *data,
                goto fin;
        }
 
-       data->outbuf = wpabuf_alloc(SHA256_DIGEST_LENGTH);
+       data->outbuf = wpabuf_alloc(SHA256_MAC_LEN);
        if (data->outbuf == NULL)
                goto fin;
 
-       wpabuf_put_data(data->outbuf, conf, SHA256_DIGEST_LENGTH);
+       wpabuf_put_data(data->outbuf, conf, SHA256_MAC_LEN);
 
 fin:
        os_free(cruft);
index 6c47dee2254e0ba8d722cec1e68150c9a90406fe..b61061bce702d5af98b2571d11459b0e12ff86a2 100644 (file)
@@ -9,6 +9,7 @@
 #include "includes.h"
 
 #include "common.h"
+#include "crypto/sha256.h"
 #include "eap_server/eap_i.h"
 #include "eap_common/eap_pwd_common.h"
 
@@ -40,7 +41,7 @@ struct eap_pwd_data {
        EC_POINT *my_element;
        EC_POINT *peer_element;
 
-       u8 my_confirm[SHA256_DIGEST_LENGTH];
+       u8 my_confirm[SHA256_MAC_LEN];
 
        u8 msk[EAP_MSK_LEN];
        u8 emsk[EAP_EMSK_LEN];
@@ -288,8 +289,8 @@ static void eap_pwd_build_confirm_req(struct eap_sm *sm,
                                      struct eap_pwd_data *data, u8 id)
 {
        BIGNUM *x = NULL, *y = NULL;
-       HMAC_CTX ctx;
-       u8 conf[SHA256_DIGEST_LENGTH], *cruft = NULL, *ptr;
+       struct crypto_hash *hash;
+       u8 conf[SHA256_MAC_LEN], *cruft = NULL, *ptr;
        u16 grp;
        int offset;
 
@@ -313,7 +314,9 @@ static void eap_pwd_build_confirm_req(struct eap_sm *sm,
         * commit is H(k | server_element | server_scalar | peer_element |
         *             peer_scalar | ciphersuite)
         */
-       H_Init(&ctx);
+       hash = eap_pwd_h_init();
+       if (hash == NULL)
+               goto fin;
 
        /*
         * Zero the memory each time because this is mod prime math and some
@@ -324,7 +327,7 @@ static void eap_pwd_build_confirm_req(struct eap_sm *sm,
        os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
        offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(data->k);
        BN_bn2bin(data->k, cruft + offset);
-       H_Update(&ctx, cruft, BN_num_bytes(data->grp->prime));
+       eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->prime));
 
        /* server element: x, y */
        if (!EC_POINT_get_affine_coordinates_GFp(data->grp->group,
@@ -338,18 +341,18 @@ static void eap_pwd_build_confirm_req(struct eap_sm *sm,
        os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
        offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(x);
        BN_bn2bin(x, cruft + offset);
-       H_Update(&ctx, cruft, BN_num_bytes(data->grp->prime));
+       eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->prime));
        os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
        offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(y);
        BN_bn2bin(y, cruft + offset);
-       H_Update(&ctx, cruft, BN_num_bytes(data->grp->prime));
+       eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->prime));
 
        /* server scalar */
        os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
        offset = BN_num_bytes(data->grp->order) -
                BN_num_bytes(data->my_scalar);
        BN_bn2bin(data->my_scalar, cruft + offset);
-       H_Update(&ctx, cruft, BN_num_bytes(data->grp->order));
+       eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->order));
 
        /* peer element: x, y */
        if (!EC_POINT_get_affine_coordinates_GFp(data->grp->group,
@@ -363,18 +366,18 @@ static void eap_pwd_build_confirm_req(struct eap_sm *sm,
        os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
        offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(x);
        BN_bn2bin(x, cruft + offset);
-       H_Update(&ctx, cruft, BN_num_bytes(data->grp->prime));
+       eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->prime));
        os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
        offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(y);
        BN_bn2bin(y, cruft + offset);
-       H_Update(&ctx, cruft, BN_num_bytes(data->grp->prime));
+       eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->prime));
 
        /* peer scalar */
        os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
        offset = BN_num_bytes(data->grp->order) -
                BN_num_bytes(data->peer_scalar);
        BN_bn2bin(data->peer_scalar, cruft + offset);
-       H_Update(&ctx, cruft, BN_num_bytes(data->grp->order));
+       eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->order));
 
        /* ciphersuite */
        grp = htons(data->group_num);
@@ -386,17 +389,17 @@ static void eap_pwd_build_confirm_req(struct eap_sm *sm,
        ptr += sizeof(u8);
        *ptr = EAP_PWD_DEFAULT_PRF;
        ptr += sizeof(u8);
-       H_Update(&ctx, cruft, ptr-cruft);
+       eap_pwd_h_update(hash, cruft, ptr - cruft);
 
        /* all done with the random function */
-       H_Final(&ctx, conf);
-       os_memcpy(data->my_confirm, conf, SHA256_DIGEST_LENGTH);
+       eap_pwd_h_final(hash, conf);
+       os_memcpy(data->my_confirm, conf, SHA256_MAC_LEN);
 
-       data->outbuf = wpabuf_alloc(SHA256_DIGEST_LENGTH);
+       data->outbuf = wpabuf_alloc(SHA256_MAC_LEN);
        if (data->outbuf == NULL)
                goto fin;
 
-       wpabuf_put_data(data->outbuf, conf, SHA256_DIGEST_LENGTH);
+       wpabuf_put_data(data->outbuf, conf, SHA256_MAC_LEN);
 
 fin:
        os_free(cruft);
@@ -404,8 +407,6 @@ fin:
        BN_free(y);
        if (data->outbuf == NULL)
                eap_pwd_state(data, FAILURE);
-
-       return;
 }
 
 
@@ -735,10 +736,10 @@ eap_pwd_process_confirm_resp(struct eap_sm *sm, struct eap_pwd_data *data,
                             const u8 *payload, size_t payload_len)
 {
        BIGNUM *x = NULL, *y = NULL;
-       HMAC_CTX ctx;
+       struct crypto_hash *hash;
        u32 cs;
        u16 grp;
-       u8 conf[SHA256_DIGEST_LENGTH], *cruft = NULL, *ptr;
+       u8 conf[SHA256_MAC_LEN], *cruft = NULL, *ptr;
        int offset;
 
        /* build up the ciphersuite: group | random_function | prf */
@@ -761,13 +762,15 @@ eap_pwd_process_confirm_resp(struct eap_sm *sm, struct eap_pwd_data *data,
         * commit is H(k | peer_element | peer_scalar | server_element |
         *             server_scalar | ciphersuite)
         */
-       H_Init(&ctx);
+       hash = eap_pwd_h_init();
+       if (hash == NULL)
+               goto fin;
 
        /* k */
        os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
        offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(data->k);
        BN_bn2bin(data->k, cruft + offset);
-       H_Update(&ctx, cruft, BN_num_bytes(data->grp->prime));
+       eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->prime));
 
        /* peer element: x, y */
        if (!EC_POINT_get_affine_coordinates_GFp(data->grp->group,
@@ -780,18 +783,18 @@ eap_pwd_process_confirm_resp(struct eap_sm *sm, struct eap_pwd_data *data,
        os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
        offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(x);
        BN_bn2bin(x, cruft + offset);
-       H_Update(&ctx, cruft, BN_num_bytes(data->grp->prime));
+       eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->prime));
        os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
        offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(y);
        BN_bn2bin(y, cruft + offset);
-       H_Update(&ctx, cruft, BN_num_bytes(data->grp->prime));
+       eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->prime));
 
        /* peer scalar */
        os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
        offset = BN_num_bytes(data->grp->order) -
                BN_num_bytes(data->peer_scalar);
        BN_bn2bin(data->peer_scalar, cruft + offset);
-       H_Update(&ctx, cruft, BN_num_bytes(data->grp->order));
+       eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->order));
 
        /* server element: x, y */
        if (!EC_POINT_get_affine_coordinates_GFp(data->grp->group,
@@ -805,28 +808,28 @@ eap_pwd_process_confirm_resp(struct eap_sm *sm, struct eap_pwd_data *data,
        os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
        offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(x);
        BN_bn2bin(x, cruft + offset);
-       H_Update(&ctx, cruft, BN_num_bytes(data->grp->prime));
+       eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->prime));
        os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
        offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(y);
        BN_bn2bin(y, cruft + offset);
-       H_Update(&ctx, cruft, BN_num_bytes(data->grp->prime));
+       eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->prime));
 
        /* server scalar */
        os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
        offset = BN_num_bytes(data->grp->order) -
                BN_num_bytes(data->my_scalar);
        BN_bn2bin(data->my_scalar, cruft + offset);
-       H_Update(&ctx, cruft, BN_num_bytes(data->grp->order));
+       eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->order));
 
        /* ciphersuite */
        os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
-       H_Update(&ctx, (u8 *)&cs, sizeof(u32));
+       eap_pwd_h_update(hash, (u8 *) &cs, sizeof(u32));
 
        /* all done */
-       H_Final(&ctx, conf);
+       eap_pwd_h_final(hash, conf);
 
        ptr = (u8 *) payload;
-       if (os_memcmp(conf, ptr, SHA256_DIGEST_LENGTH)) {
+       if (os_memcmp(conf, ptr, SHA256_MAC_LEN)) {
                wpa_printf(MSG_INFO, "EAP-PWD (server): confirm did not "
                           "verify");
                goto fin;