/** * crypto_hash_data(key, data, len, buf): * Hash the provided data with the HMAC-SHA256 key specified; or if * ${key} == CRYPTO_KEY_HMAC_SHA256, just SHA256 the data. */ int crypto_hash_data(int key, const uint8_t * data, size_t len, uint8_t buf[32]) { /* Use crypto_hash_data_2 to do the work. */ return (crypto_hash_data_2(key, data, len, NULL, 0, buf)); }
/** * netpacket_hmac_append(type, packetbuf, len, key): * HMAC (type || packetbuf[0 .. len - 1]) using the specified key and write * the result into packetbuf[len .. len + 31]. */ int netpacket_hmac_append(uint8_t type, uint8_t * packetbuf, size_t len, int key) { return (crypto_hash_data_2(key, &type, 1, packetbuf, len, &packetbuf[len])); }
/** * netpacket_hmac_verify(type, nonce, packetbuf, pos, key): * Verify that HMAC(type || nonce || packetbuf[0 .. pos - 1]) using the * specified key matches packetbuf[pos .. pos + 31]. If nonce is NULL, omit * it from the data being HMACed as appropriate. Return -1 on error, 0 on * success, or 1 if the hash does not match. */ int netpacket_hmac_verify(uint8_t type, const uint8_t nonce[32], const uint8_t * packetbuf, size_t pos, int key) { uint8_t hmac_actual[32]; uint8_t prefixbuf[33]; size_t prefixlen; /* Compute the correct HMAC. */ prefixbuf[0] = type; prefixlen = 1; if (nonce != NULL) { memcpy(&prefixbuf[prefixlen], nonce, 32); prefixlen += 32; } if (crypto_hash_data_2(key, prefixbuf, prefixlen, packetbuf, pos, hmac_actual)) goto err0; /* Compare. */ if (crypto_verify_bytes(&packetbuf[pos], hmac_actual, 32)) goto badhmac; /* Success! */ return (0); badhmac: /* HMAC doesn't match. */ return (1); err0: /* Failure! */ return (-1); }
/** * crypto_MGF1(seed, seedlen, buf, buflen): * The MGF1 mask generation function, as specified in RFC 3447. */ void crypto_MGF1(uint8_t * seed, size_t seedlen, uint8_t * buf, size_t buflen) { uint8_t hbuf[32]; size_t pos; uint32_t i; uint8_t C[4]; /* Sanity check for I2OSP function. */ assert(((buflen - 1) / 32) <= UINT32_MAX); /* Iterate through the buffer. */ for (pos = 0; pos < buflen; pos += 32) { /* The ith block starts at position i * 32. */ i = (uint32_t)(pos / 32); /* Convert counter to big-endian format. */ be32enc(C, i); /* Compute the hash of (seed || C). */ if (crypto_hash_data_2(CRYPTO_KEY_HMAC_SHA256, seed, seedlen, C, 4, hbuf)) { warn0("Programmer error: " "SHA256 should never fail"); abort(); } /* Copy as much data as needed. */ if (buflen - pos > 32) memcpy(buf + pos, hbuf, 32); else memcpy(buf + pos, hbuf, buflen - pos); } }