- * Keyed-Hashing for Message Authentication: FIPS 198 (RFC 2104) * * Compute the HMAC digest using the desired hash key, text, and HMAC * algorithm. Resulting digest is placed in 'digest' and digest length * is returned, if the HMAC was performed. * * WARNING: it is up to the caller to supply sufficient space to hold the * resultant digest. */
| 912 | * resultant digest. |
| 913 | */ |
| 914 | uint32_t |
| 915 | sctp_hmac(uint16_t hmac_algo, uint8_t *key, uint32_t keylen, |
| 916 | uint8_t *text, uint32_t textlen, uint8_t *digest) |
| 917 | { |
| 918 | uint32_t digestlen; |
| 919 | uint32_t blocklen; |
| 920 | sctp_hash_context_t ctx; |
| 921 | uint8_t ipad[128], opad[128]; /* keyed hash inner/outer pads */ |
| 922 | uint8_t temp[SCTP_AUTH_DIGEST_LEN_MAX]; |
| 923 | uint32_t i; |
| 924 | |
| 925 | /* sanity check the material and length */ |
| 926 | if ((key == NULL) || (keylen == 0) || (text == NULL) || |
| 927 | (textlen == 0) || (digest == NULL)) { |
| 928 | /* can't do HMAC with empty key or text or digest store */ |
| 929 | return (0); |
| 930 | } |
| 931 | /* validate the hmac algo and get the digest length */ |
| 932 | digestlen = sctp_get_hmac_digest_len(hmac_algo); |
| 933 | if (digestlen == 0) |
| 934 | return (0); |
| 935 | |
| 936 | /* hash the key if it is longer than the hash block size */ |
| 937 | blocklen = sctp_get_hmac_block_len(hmac_algo); |
| 938 | if (keylen > blocklen) { |
| 939 | sctp_hmac_init(hmac_algo, &ctx); |
| 940 | sctp_hmac_update(hmac_algo, &ctx, key, keylen); |
| 941 | sctp_hmac_final(hmac_algo, &ctx, temp); |
| 942 | /* set the hashed key as the key */ |
| 943 | keylen = digestlen; |
| 944 | key = temp; |
| 945 | } |
| 946 | /* initialize the inner/outer pads with the key and "append" zeroes */ |
| 947 | memset(ipad, 0, blocklen); |
| 948 | memset(opad, 0, blocklen); |
| 949 | memcpy(ipad, key, keylen); |
| 950 | memcpy(opad, key, keylen); |
| 951 | |
| 952 | /* XOR the key with ipad and opad values */ |
| 953 | for (i = 0; i < blocklen; i++) { |
| 954 | ipad[i] ^= 0x36; |
| 955 | opad[i] ^= 0x5c; |
| 956 | } |
| 957 | |
| 958 | /* perform inner hash */ |
| 959 | sctp_hmac_init(hmac_algo, &ctx); |
| 960 | sctp_hmac_update(hmac_algo, &ctx, ipad, blocklen); |
| 961 | sctp_hmac_update(hmac_algo, &ctx, text, textlen); |
| 962 | sctp_hmac_final(hmac_algo, &ctx, temp); |
| 963 | |
| 964 | /* perform outer hash */ |
| 965 | sctp_hmac_init(hmac_algo, &ctx); |
| 966 | sctp_hmac_update(hmac_algo, &ctx, opad, blocklen); |
| 967 | sctp_hmac_update(hmac_algo, &ctx, temp, digestlen); |
| 968 | sctp_hmac_final(hmac_algo, &ctx, digest); |
| 969 | |
| 970 | return (digestlen); |
| 971 | } |
no test coverage detected