File hmac.patch of Package gnutls
Index: gnutls-3.8.6/lib/fips.c
===================================================================
--- gnutls-3.8.6.orig/lib/fips.c
+++ gnutls-3.8.6/lib/fips.c
@@ -349,6 +349,13 @@ static int load_hmac_file(struct hmac_fi
*
* Verify that HMAC from hmac file entry matches HMAC of given library.
*
+ * This check can fail if any of the dynamically linked libraries
+ * (libgnutls, libnettle, lighogweed or libgmp) gets updated as the
+ * calculated HMAC during build time will differ from the stored
+ * values in the gnutls HMAC file called .libgnutls.so.<soname>.hmac.
+ * In this case, we compare the calculated HMAC with the provided by
+ * each library and named .<libname>.so.<soname>.hmac.
+ *
* Returns: 0 on successful HMAC verification, a negative error code otherwise
*/
static int check_lib_hmac(struct hmac_entry *entry, const char *path)
@@ -357,6 +364,9 @@ static int check_lib_hmac(struct hmac_en
unsigned prev;
uint8_t hmac[HMAC_SIZE];
gnutls_datum_t data;
+ char hmac_path[GNUTLS_PATH_MAX];
+ uint8_t lib_hmac[HMAC_SIZE];
+ size_t lib_hmac_size;
_gnutls_debug_log("Loading: %s\n", path);
ret = gnutls_load_file(path, &data);
@@ -379,11 +389,45 @@ static int check_lib_hmac(struct hmac_en
return gnutls_assert_val(ret);
}
- if (gnutls_memcmp(entry->hmac, hmac, HMAC_SIZE)) {
- _gnutls_debug_log("Calculated MAC for %s does not match\n",
- path);
+ ret = gnutls_memcmp(entry->hmac, hmac, HMAC_SIZE);
+ if (ret) {
+ /* Check now the integrity of the hmac provided by the library */
+ ret = get_hmac_path(hmac_path, sizeof(hmac_path), path);
+ if (ret < 0) {
+ _gnutls_debug_log("Could not get hmac file path: %s\n",
+ gnutls_strerror(ret));
+ return ret;
+ }
+ _gnutls_debug_log("Loading: %s\n", hmac_path);
+ ret = gnutls_load_file(hmac_path, &data);
+ if (ret < 0) {
+ _gnutls_debug_log("Could not load %s: %s\n", hmac_path,
+ gnutls_strerror(ret));
+ return gnutls_assert_val(ret);
+ }
+ // lib_hmac_size = HMAC_SIZE;
+ lib_hmac_size = hex_data_size(data.size);
+ /* trim eventual newlines from the end of the data read from file */
+ while ((data.size > 0) && (data.data[data.size - 1] == '\n')) {
+ data.data[data.size - 1] = 0;
+ data.size--;
+ }
+ ret = gnutls_hex_decode(&data, lib_hmac, &lib_hmac_size);
+ gnutls_free(data.data);
+ if (ret < 0) {
+ _gnutls_debug_log("Could not hex decode hmac\n");
+ return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
+ }
+ ret = gnutls_memcmp(lib_hmac, hmac, HMAC_SIZE);
+ if (ret){
+ _gnutls_debug_log("Calculated MAC for %s does not match\n",
+ path);
+ gnutls_memset(hmac, 0, HMAC_SIZE);
+ gnutls_memset(lib_hmac, 0, HMAC_SIZE);
+ return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
+ }
gnutls_memset(hmac, 0, HMAC_SIZE);
- return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
+ gnutls_memset(lib_hmac, 0, HMAC_SIZE);
}
_gnutls_debug_log("Successfully verified MAC for %s\n", path);