mbuf version */
| 972 | |
| 973 | /* mbuf version */ |
| 974 | uint32_t |
| 975 | sctp_hmac_m(uint16_t hmac_algo, uint8_t *key, uint32_t keylen, |
| 976 | struct mbuf *m, uint32_t m_offset, uint8_t *digest, uint32_t trailer) |
| 977 | { |
| 978 | uint32_t digestlen; |
| 979 | uint32_t blocklen; |
| 980 | sctp_hash_context_t ctx; |
| 981 | uint8_t ipad[128], opad[128]; /* keyed hash inner/outer pads */ |
| 982 | uint8_t temp[SCTP_AUTH_DIGEST_LEN_MAX]; |
| 983 | uint32_t i; |
| 984 | struct mbuf *m_tmp; |
| 985 | |
| 986 | /* sanity check the material and length */ |
| 987 | if ((key == NULL) || (keylen == 0) || (m == NULL) || (digest == NULL)) { |
| 988 | /* can't do HMAC with empty key or text or digest store */ |
| 989 | return (0); |
| 990 | } |
| 991 | /* validate the hmac algo and get the digest length */ |
| 992 | digestlen = sctp_get_hmac_digest_len(hmac_algo); |
| 993 | if (digestlen == 0) |
| 994 | return (0); |
| 995 | |
| 996 | /* hash the key if it is longer than the hash block size */ |
| 997 | blocklen = sctp_get_hmac_block_len(hmac_algo); |
| 998 | if (keylen > blocklen) { |
| 999 | sctp_hmac_init(hmac_algo, &ctx); |
| 1000 | sctp_hmac_update(hmac_algo, &ctx, key, keylen); |
| 1001 | sctp_hmac_final(hmac_algo, &ctx, temp); |
| 1002 | /* set the hashed key as the key */ |
| 1003 | keylen = digestlen; |
| 1004 | key = temp; |
| 1005 | } |
| 1006 | /* initialize the inner/outer pads with the key and "append" zeroes */ |
| 1007 | memset(ipad, 0, blocklen); |
| 1008 | memset(opad, 0, blocklen); |
| 1009 | memcpy(ipad, key, keylen); |
| 1010 | memcpy(opad, key, keylen); |
| 1011 | |
| 1012 | /* XOR the key with ipad and opad values */ |
| 1013 | for (i = 0; i < blocklen; i++) { |
| 1014 | ipad[i] ^= 0x36; |
| 1015 | opad[i] ^= 0x5c; |
| 1016 | } |
| 1017 | |
| 1018 | /* perform inner hash */ |
| 1019 | sctp_hmac_init(hmac_algo, &ctx); |
| 1020 | sctp_hmac_update(hmac_algo, &ctx, ipad, blocklen); |
| 1021 | /* find the correct starting mbuf and offset (get start of text) */ |
| 1022 | m_tmp = m; |
| 1023 | while ((m_tmp != NULL) && (m_offset >= (uint32_t)SCTP_BUF_LEN(m_tmp))) { |
| 1024 | m_offset -= SCTP_BUF_LEN(m_tmp); |
| 1025 | m_tmp = SCTP_BUF_NEXT(m_tmp); |
| 1026 | } |
| 1027 | /* now use the rest of the mbuf chain for the text */ |
| 1028 | while (m_tmp != NULL) { |
| 1029 | if ((SCTP_BUF_NEXT(m_tmp) == NULL) && trailer) { |
| 1030 | sctp_hmac_update(hmac_algo, &ctx, mtod(m_tmp, uint8_t *)+m_offset, |
| 1031 | SCTP_BUF_LEN(m_tmp) - (trailer + m_offset)); |
no test coverage detected