From: Michael Tremer Date: Fri, 26 Aug 2022 08:21:33 +0000 (+0000) Subject: digest: Add support for SHA-3 X-Git-Tag: 0.9.28~362 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d98740de58d03815f9b2226401810e4978243e1b;p=pakfire.git digest: Add support for SHA-3 Signed-off-by: Michael Tremer --- diff --git a/src/libpakfire/digest.c b/src/libpakfire/digest.c index c35be92c6..e57ffc972 100644 --- a/src/libpakfire/digest.c +++ b/src/libpakfire/digest.c @@ -33,6 +33,12 @@ size_t pakfire_digest_length(const enum pakfire_digest_types digest) { switch (digest) { + case PAKFIRE_DIGEST_SHA3_512: + return SHA512_DIGEST_LENGTH; + + case PAKFIRE_DIGEST_SHA3_256: + return SHA256_DIGEST_LENGTH; + case PAKFIRE_DIGEST_BLAKE2B512: return BLAKE2B512_DIGEST_LENGTH; @@ -68,6 +74,22 @@ void pakfire_digests_reset(struct pakfire_digests* digests, int types) { if (!types) types = ~types; + // Reset SHA-3-512 + if (types & PAKFIRE_DIGEST_SHA3_512) + memset(digests->sha3_512, 0, sizeof(digests->sha3_512)); + + // Reset SHA-3-256 + if (types & PAKFIRE_DIGEST_SHA3_256) + memset(digests->sha3_256, 0, sizeof(digests->sha3_256)); + + // Reset BLAKE2b512 + if (types & PAKFIRE_DIGEST_BLAKE2B512) + memset(digests->blake2b512, 0, sizeof(digests->blake2b512)); + + // Reset BLAKE2s256 + if (types & PAKFIRE_DIGEST_BLAKE2S256) + memset(digests->blake2s256, 0, sizeof(digests->blake2s256)); + // Reset SHA-2-512 if (types & PAKFIRE_DIGEST_SHA2_512) memset(digests->sha2_512, 0, sizeof(digests->sha2_512)); @@ -163,6 +185,8 @@ static int __pakfire_digest_finalize(struct pakfire* pakfire, int pakfire_digests_compute_from_file(struct pakfire* pakfire, struct pakfire_digests* digests, const int types, FILE* f) { + EVP_MD_CTX* sha3_512_ctx = NULL; + EVP_MD_CTX* sha3_256_ctx = NULL; EVP_MD_CTX* blake2b512_ctx = NULL; EVP_MD_CTX* blake2s256_ctx = NULL; EVP_MD_CTX* sha2_512_ctx = NULL; @@ -170,6 +194,20 @@ int pakfire_digests_compute_from_file(struct pakfire* pakfire, char buffer[PAKFIRE_BUFFER_SIZE]; int r = 1; + // Initialize context for SHA-3-512 + if (types & PAKFIRE_DIGEST_SHA3_512) { + sha3_512_ctx = __pakfire_digest_setup(pakfire, EVP_sha3_512()); + if (!sha3_512_ctx) + goto ERROR; + } + + // Initialize context for SHA-3-256 + if (types & PAKFIRE_DIGEST_SHA3_256) { + sha3_256_ctx = __pakfire_digest_setup(pakfire, EVP_sha3_256()); + if (!sha3_256_ctx) + goto ERROR; + } + // Initialize context for BLAKE2B512 if (types & PAKFIRE_DIGEST_BLAKE2B512) { blake2b512_ctx = __pakfire_digest_setup(pakfire, EVP_blake2b512()); @@ -184,14 +222,14 @@ int pakfire_digests_compute_from_file(struct pakfire* pakfire, goto ERROR; } - // Initialize context for SHA-512 + // Initialize context for SHA-2-512 if (types & PAKFIRE_DIGEST_SHA2_512) { sha2_512_ctx = __pakfire_digest_setup(pakfire, EVP_sha512()); if (!sha2_512_ctx) goto ERROR; } - // Initialize context for SHA-256 + // Initialize context for SHA-2-256 if (types & PAKFIRE_DIGEST_SHA2_256) { sha2_256_ctx = __pakfire_digest_setup(pakfire, EVP_sha256()); if (!sha2_256_ctx) @@ -208,6 +246,16 @@ int pakfire_digests_compute_from_file(struct pakfire* pakfire, goto ERROR; } + // SHA-3-512 + r = __pakfire_digest_update(pakfire, sha3_512_ctx, buffer, bytes_read); + if (r) + goto ERROR; + + // SHA-3-256 + r = __pakfire_digest_update(pakfire, sha3_256_ctx, buffer, bytes_read); + if (r) + goto ERROR; + // BLAKE2B512 r = __pakfire_digest_update(pakfire, blake2b512_ctx, buffer, bytes_read); if (r) @@ -229,6 +277,16 @@ int pakfire_digests_compute_from_file(struct pakfire* pakfire, goto ERROR; } + // Finalize SHA-3-512 + r = __pakfire_digest_finalize(pakfire, sha3_512_ctx, digests->sha3_512); + if (r) + goto ERROR; + + // Finalize SHA-3-256 + r = __pakfire_digest_finalize(pakfire, sha3_256_ctx, digests->sha3_256); + if (r) + goto ERROR; + // Finalize BLAKE2b512 r = __pakfire_digest_finalize(pakfire, blake2b512_ctx, digests->blake2b512); if (r) @@ -239,12 +297,12 @@ int pakfire_digests_compute_from_file(struct pakfire* pakfire, if (r) goto ERROR; - // Finalize SHA-512 + // Finalize SHA-2-512 r = __pakfire_digest_finalize(pakfire, sha2_512_ctx, digests->sha2_512); if (r) goto ERROR; - // Finalize SHA-256 + // Finalize SHA-2-256 r = __pakfire_digest_finalize(pakfire, sha2_256_ctx, digests->sha2_256); if (r) goto ERROR; @@ -253,6 +311,10 @@ int pakfire_digests_compute_from_file(struct pakfire* pakfire, r = 0; ERROR: + if (sha3_512_ctx) + EVP_MD_CTX_free(sha3_512_ctx); + if (sha3_256_ctx) + EVP_MD_CTX_free(sha3_256_ctx); if (blake2b512_ctx) EVP_MD_CTX_free(blake2b512_ctx); if (blake2s256_ctx) @@ -296,6 +358,26 @@ int pakfire_digests_compare(struct pakfire* pakfire, const struct pakfire_digest return 1; } + // Check SHA-3-512 + if (types & PAKFIRE_DIGEST_SHA3_512) { + r = CRYPTO_memcmp(digests1->sha3_512, digests2->sha3_512, sizeof(digests1->sha3_512)); + if (r) { + pakfire_digests_compare_mismatch(pakfire, "SHA-3-512", + digests1->sha3_512, digests2->sha3_512, sizeof(digests1->sha3_512)); + return 1; + } + } + + // Check SHA-3-256 + if (types & PAKFIRE_DIGEST_SHA3_256) { + r = CRYPTO_memcmp(digests1->sha3_256, digests2->sha3_256, sizeof(digests1->sha3_256)); + if (r) { + pakfire_digests_compare_mismatch(pakfire, "SHA-3-256", + digests1->sha3_256, digests2->sha3_256, sizeof(digests1->sha3_256)); + return 1; + } + } + // Check BLAKE2b512 if (types & PAKFIRE_DIGEST_BLAKE2B512) { r = CRYPTO_memcmp(digests1->blake2b512, digests2->blake2b512, sizeof(digests1->blake2b512)); @@ -316,7 +398,7 @@ int pakfire_digests_compare(struct pakfire* pakfire, const struct pakfire_digest } } - // Check SHA-512 + // Check SHA-2-512 if (types & PAKFIRE_DIGEST_SHA2_512) { r = CRYPTO_memcmp(digests1->sha2_512, digests2->sha2_512, sizeof(digests1->sha2_512)); if (r) { @@ -326,7 +408,7 @@ int pakfire_digests_compare(struct pakfire* pakfire, const struct pakfire_digest } } - // Check SHA-256 + // Check SHA-2-256 if (types & PAKFIRE_DIGEST_SHA2_256) { r = CRYPTO_memcmp(digests1->sha2_256, digests2->sha2_256, sizeof(digests1->sha2_256)); if (r) { @@ -351,6 +433,14 @@ int pakfire_digests_compare_one(struct pakfire* pakfire, struct pakfire_digests* return r; switch (type) { + case PAKFIRE_DIGEST_SHA3_512: + memcpy(digests2.sha3_512, digest, sizeof(digests2.sha3_512)); + break; + + case PAKFIRE_DIGEST_SHA3_256: + memcpy(digests2.sha3_256, digest, sizeof(digests2.sha3_256)); + break; + case PAKFIRE_DIGEST_BLAKE2B512: memcpy(digests2.blake2b512, digest, sizeof(digests2.blake2b512)); break; diff --git a/src/libpakfire/downloader.c b/src/libpakfire/downloader.c index c5947d1ea..113eb3b1b 100644 --- a/src/libpakfire/downloader.c +++ b/src/libpakfire/downloader.c @@ -346,6 +346,14 @@ static struct pakfire_transfer* pakfire_downloader_create_transfer( // Set message digest switch (md) { + case PAKFIRE_DIGEST_SHA3_512: + transfer->md = EVP_sha3_512(); + break; + + case PAKFIRE_DIGEST_SHA3_256: + transfer->md = EVP_sha3_256(); + break; + case PAKFIRE_DIGEST_BLAKE2B512: transfer->md = EVP_blake2b512(); break; diff --git a/src/libpakfire/file.c b/src/libpakfire/file.c index e42e8622c..80454ab40 100644 --- a/src/libpakfire/file.c +++ b/src/libpakfire/file.c @@ -139,8 +139,20 @@ static int pakfire_file_from_archive_entry(struct pakfire_file* file, struct arc // Read any extended attributes while (archive_entry_xattr_next(entry, &attr, &value, &size) == ARCHIVE_OK) { + // Digest: SHA-3-512 + if (strcmp(attr, "PAKFIRE.digests.sha3_512") == 0) { + r = pakfire_file_set_digest(file, PAKFIRE_DIGEST_SHA3_512, value, size); + if (r) + goto ERROR; + + // Digest: SHA-3-256 + } else if (strcmp(attr, "PAKFIRE.digests.sha3_256") == 0) { + r = pakfire_file_set_digest(file, PAKFIRE_DIGEST_SHA3_256, value, size); + if (r) + goto ERROR; + // Digest: BLAKE2b512 - if (strcmp(attr, "PAKFIRE.digests.blake2b512") == 0) { + } else if (strcmp(attr, "PAKFIRE.digests.blake2b512") == 0) { r = pakfire_file_set_digest(file, PAKFIRE_DIGEST_BLAKE2B512, value, size); if (r) goto ERROR; @@ -286,6 +298,16 @@ struct archive_entry* pakfire_file_archive_entry(struct pakfire_file* file) { // Copy digests + // SHA-3-512 + if (pakfire_digest_set(file->digests.sha3_512)) + archive_entry_xattr_add_entry(entry, "PAKFIRE.digests.sha3_512", + file->digests.sha3_512, sizeof(file->digests.sha3_512)); + + // SHA-3-256 + if (pakfire_digest_set(file->digests.sha3_256)) + archive_entry_xattr_add_entry(entry, "PAKFIRE.digests.sha3_256", + file->digests.sha3_256, sizeof(file->digests.sha3_256)); + // BLAKE2b512 if (pakfire_digest_set(file->digests.blake2b512)) archive_entry_xattr_add_entry(entry, "PAKFIRE.digests.blake2b512", @@ -481,6 +503,24 @@ PAKFIRE_EXPORT const unsigned char* pakfire_file_get_digest( struct pakfire_file* file, const enum pakfire_digest_types type, size_t* length) { switch (type) { + case PAKFIRE_DIGEST_SHA3_512: + if (!pakfire_digest_set(file->digests.sha3_512)) + return NULL; + + if (length) + *length = sizeof(file->digests.sha3_512); + + return file->digests.sha3_512; + + case PAKFIRE_DIGEST_SHA3_256: + if (!pakfire_digest_set(file->digests.sha3_256)) + return NULL; + + if (length) + *length = sizeof(file->digests.sha3_256); + + return file->digests.sha3_256; + case PAKFIRE_DIGEST_BLAKE2B512: if (!pakfire_digest_set(file->digests.blake2b512)) return NULL; @@ -540,6 +580,14 @@ PAKFIRE_EXPORT int pakfire_file_set_digest(struct pakfire_file* file, // Store the digest switch (type) { + case PAKFIRE_DIGEST_SHA3_512: + memcpy(file->digests.sha3_512, digest, sizeof(file->digests.sha3_512)); + break; + + case PAKFIRE_DIGEST_SHA3_256: + memcpy(file->digests.sha3_256, digest, sizeof(file->digests.sha3_256)); + break; + case PAKFIRE_DIGEST_BLAKE2B512: memcpy(file->digests.blake2b512, digest, sizeof(file->digests.blake2b512)); break; @@ -830,6 +878,18 @@ static int pakfire_file_verify_payload(struct pakfire_file* file, const struct s } // Check if this file has any digests at all + if (pakfire_digest_set(file->digests.sha3_512)) + digest_types |= PAKFIRE_DIGEST_SHA3_512; + + if (pakfire_digest_set(file->digests.sha3_256)) + digest_types |= PAKFIRE_DIGEST_SHA3_256; + + if (pakfire_digest_set(file->digests.blake2b512)) + digest_types |= PAKFIRE_DIGEST_BLAKE2B512; + + if (pakfire_digest_set(file->digests.blake2s256)) + digest_types |= PAKFIRE_DIGEST_BLAKE2S256; + if (pakfire_digest_set(file->digests.sha2_512)) digest_types |= PAKFIRE_DIGEST_SHA2_512; diff --git a/src/libpakfire/include/pakfire/digest.h b/src/libpakfire/include/pakfire/digest.h index 6b6072907..e427cda10 100644 --- a/src/libpakfire/include/pakfire/digest.h +++ b/src/libpakfire/include/pakfire/digest.h @@ -28,6 +28,8 @@ enum pakfire_digest_types { PAKFIRE_DIGEST_SHA2_512 = (1 << 1), PAKFIRE_DIGEST_BLAKE2S256 = (1 << 2), PAKFIRE_DIGEST_BLAKE2B512 = (1 << 3), + PAKFIRE_DIGEST_SHA3_256 = (1 << 4), + PAKFIRE_DIGEST_SHA3_512 = (1 << 5), }; #define PAKFIRE_DIGESTS_ALL (~PAKFIRE_DIGEST_UNDEFINED) @@ -54,6 +56,12 @@ enum pakfire_digest_types { // Digests struct pakfire_digests { + // SHA-3-512 + unsigned char sha3_512[SHA512_DIGEST_LENGTH]; + + // SHA-3-256 + unsigned char sha3_256[SHA256_DIGEST_LENGTH]; + // BLAKE2b512 unsigned char blake2b512[BLAKE2B512_DIGEST_LENGTH]; @@ -69,6 +77,8 @@ struct pakfire_digests { #define PAKFIRE_DIGESTS_INIT \ { \ + .sha3_512 = 0, \ + .sha3_256 = 0, \ .blake2b512 = 0, \ .blake2s256 = 0, \ .sha2_512 = 0, \ diff --git a/src/libpakfire/package.c b/src/libpakfire/package.c index 9f56e5656..530ce6d3f 100644 --- a/src/libpakfire/package.c +++ b/src/libpakfire/package.c @@ -1149,6 +1149,8 @@ PAKFIRE_EXPORT char* pakfire_package_dump(struct pakfire_package* pkg, int flags pakfire_package_dump_add_line(&string, _("SHA256 Digest"), hexdigest); break; + case PAKFIRE_DIGEST_SHA3_512: + case PAKFIRE_DIGEST_SHA3_256: case PAKFIRE_DIGEST_BLAKE2B512: case PAKFIRE_DIGEST_BLAKE2S256: case PAKFIRE_DIGEST_UNDEFINED: