| 127 | // |
| 128 | |
| 129 | ssize_t // O - The length of the HMAC or `-1` on error |
| 130 | cupsHMACData( |
| 131 | const char *algorithm, // I - Hash algorithm |
| 132 | const unsigned char *key, // I - Key |
| 133 | size_t keylen, // I - Length of key |
| 134 | const void *data, // I - Data to hash |
| 135 | size_t datalen, // I - Length of data to hash |
| 136 | unsigned char *hmac, // I - HMAC buffer |
| 137 | size_t hmacsize) // I - Size of HMAC buffer |
| 138 | { |
| 139 | size_t i, // Looping var |
| 140 | b; // Block size |
| 141 | unsigned char buffer[128], // Intermediate buffer |
| 142 | hash[128], // Hash buffer |
| 143 | hkey[128]; // Hashed key buffer |
| 144 | ssize_t hashlen; // Length of hash |
| 145 | |
| 146 | |
| 147 | // Range check input... |
| 148 | if (!algorithm || !key || keylen == 0 || !data || datalen == 0 || !hmac || hmacsize < 32) |
| 149 | return (-1); |
| 150 | |
| 151 | // Determine the block size... |
| 152 | if (!strcmp(algorithm, "sha2-384") || !strncmp(algorithm, "sha2-512", 8)) |
| 153 | b = 128; |
| 154 | else |
| 155 | b = 64; |
| 156 | |
| 157 | // If the key length is larger than the block size, hash it and use that |
| 158 | // instead... |
| 159 | if (keylen > b) |
| 160 | { |
| 161 | if ((hashlen = hash_data(algorithm, hkey, sizeof(hkey), key, keylen, NULL, 0)) < 0) |
| 162 | return (-1); |
| 163 | |
| 164 | key = hkey; |
| 165 | keylen = (size_t)hashlen; |
| 166 | } |
| 167 | |
| 168 | // HMAC = H(K' ^ opad, H(K' ^ ipad, data)) |
| 169 | // K' = Klen > b ? H(K) : K, padded with 0's |
| 170 | // opad = 0x5c, ipad = 0x36 |
| 171 | for (i = 0; i < b && i < keylen; i ++) |
| 172 | buffer[i] = key[i] ^ 0x36; |
| 173 | for (; i < b; i ++) |
| 174 | buffer[i] = 0x36; |
| 175 | |
| 176 | if ((hashlen = hash_data(algorithm, hash, sizeof(hash), buffer, b, data, datalen)) < 0) |
| 177 | return (-1); |
| 178 | |
| 179 | for (i = 0; i < b && i < keylen; i ++) |
| 180 | buffer[i] = key[i] ^ 0x5c; |
| 181 | for (; i < b; i ++) |
| 182 | buffer[i] = 0x5c; |
| 183 | |
| 184 | return (hash_data(algorithm, hmac, hmacsize, buffer, b, hash, (size_t)hashlen)); |
| 185 | } |
| 186 |
nothing calls this directly
no test coverage detected