From: Michael Tremer Date: Wed, 24 Aug 2022 18:02:36 +0000 (+0000) Subject: digest: Add support for BLAKE2b512/BLAKE2s256 X-Git-Tag: 0.9.28~365 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f1e6c5df9a6e6f445c9d8d774d16d0ce924bdddf;p=pakfire.git digest: Add support for BLAKE2b512/BLAKE2s256 Signed-off-by: Michael Tremer --- diff --git a/src/libpakfire/digest.c b/src/libpakfire/digest.c index 68100faf3..9cdba02d1 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_BLAKE2B512: + return BLAKE2B512_DIGEST_LENGTH; + + case PAKFIRE_DIGEST_BLAKE2S256: + return BLAKE2S256_DIGEST_LENGTH; + case PAKFIRE_DIGEST_SHA512: return SHA512_DIGEST_LENGTH; @@ -119,11 +125,27 @@ ERROR: int pakfire_digests_compute_from_file(struct pakfire* pakfire, struct pakfire_digests* digests, const int types, FILE* f) { + EVP_MD_CTX* blake2b512_ctx = NULL; + EVP_MD_CTX* blake2s256_ctx = NULL; EVP_MD_CTX* sha512_ctx = NULL; EVP_MD_CTX* sha256_ctx = NULL; char buffer[PAKFIRE_BUFFER_SIZE]; int r = 1; + // Initialize context for BLAKE2B512 + if (types & PAKFIRE_DIGEST_BLAKE2B512) { + blake2b512_ctx = __pakfire_digest_setup(pakfire, EVP_blake2b512()); + if (!blake2b512_ctx) + goto ERROR; + } + + // Initialize context for BLAKE2S256 + if (types & PAKFIRE_DIGEST_BLAKE2S256) { + blake2s256_ctx = __pakfire_digest_setup(pakfire, EVP_blake2s256()); + if (!blake2s256_ctx) + goto ERROR; + } + // Initialize context for SHA-512 if (types & PAKFIRE_DIGEST_SHA512) { sha512_ctx = __pakfire_digest_setup(pakfire, EVP_sha512()); @@ -148,6 +170,28 @@ int pakfire_digests_compute_from_file(struct pakfire* pakfire, goto ERROR; } + // BLAKE2B512 + if (blake2b512_ctx) { + r = EVP_DigestUpdate(blake2b512_ctx, buffer, bytes_read); + if (r != 1) { + ERROR(pakfire, "EVP_Digest_Update() failed: %s\n", + ERR_error_string(ERR_get_error(), NULL)); + r = 1; + goto ERROR; + } + } + + // BLAKE2S256 + if (blake2s256_ctx) { + r = EVP_DigestUpdate(blake2s256_ctx, buffer, bytes_read); + if (r != 1) { + ERROR(pakfire, "EVP_Digest_Update() failed: %s\n", + ERR_error_string(ERR_get_error(), NULL)); + r = 1; + goto ERROR; + } + } + // SHA-512 if (sha512_ctx) { r = EVP_DigestUpdate(sha512_ctx, buffer, bytes_read); @@ -171,6 +215,28 @@ int pakfire_digests_compute_from_file(struct pakfire* pakfire, } } + // Finalize BLAKE2b512 + if (blake2b512_ctx) { + r = EVP_DigestFinal_ex(blake2b512_ctx, digests->blake2b512, NULL); + if (r != 1) { + ERROR(pakfire, "EVP_DigestFinal_ex() failed: %s\n", + ERR_error_string(ERR_get_error(), NULL)); + r = 1; + goto ERROR; + } + } + + // Finalize BLAKE2s256 + if (blake2s256_ctx) { + r = EVP_DigestFinal_ex(blake2s256_ctx, digests->blake2s256, NULL); + if (r != 1) { + ERROR(pakfire, "EVP_DigestFinal_ex() failed: %s\n", + ERR_error_string(ERR_get_error(), NULL)); + r = 1; + goto ERROR; + } + } + // Finalize SHA-512 if (sha512_ctx) { r = EVP_DigestFinal_ex(sha512_ctx, digests->sha512, NULL); @@ -197,6 +263,10 @@ int pakfire_digests_compute_from_file(struct pakfire* pakfire, r = 0; ERROR: + if (blake2b512_ctx) + EVP_MD_CTX_free(blake2b512_ctx); + if (blake2s256_ctx) + EVP_MD_CTX_free(blake2s256_ctx); if (sha512_ctx) EVP_MD_CTX_free(sha512_ctx); if (sha256_ctx) @@ -236,6 +306,26 @@ int pakfire_digests_compare(struct pakfire* pakfire, const struct pakfire_digest return 1; } + // Check BLAKE2b512 + if (types & PAKFIRE_DIGEST_BLAKE2B512) { + r = CRYPTO_memcmp(digests1->blake2b512, digests2->blake2b512, sizeof(digests1->blake2b512)); + if (r) { + pakfire_digests_compare_mismatch(pakfire, "BLAKE2b512", + digests1->blake2b512, digests2->blake2b512, sizeof(digests1->blake2b512)); + return 1; + } + } + + // Check BLAKE2s256 + if (types & PAKFIRE_DIGEST_BLAKE2S256) { + r = CRYPTO_memcmp(digests1->blake2s256, digests2->blake2s256, sizeof(digests1->blake2s256)); + if (r) { + pakfire_digests_compare_mismatch(pakfire, "BLAKE2s256", + digests1->blake2s256, digests2->blake2s256, sizeof(digests1->blake2s256)); + return 1; + } + } + // Check SHA-512 if (types & PAKFIRE_DIGEST_SHA512) { r = CRYPTO_memcmp(digests1->sha512, digests2->sha512, sizeof(digests1->sha512)); @@ -271,6 +361,14 @@ int pakfire_digests_compare_one(struct pakfire* pakfire, struct pakfire_digests* return r; switch (type) { + case PAKFIRE_DIGEST_BLAKE2B512: + memcpy(digests2.blake2b512, digest, sizeof(digests2.blake2b512)); + break; + + case PAKFIRE_DIGEST_BLAKE2S256: + memcpy(digests2.blake2s256, digest, sizeof(digests2.blake2s256)); + break; + case PAKFIRE_DIGEST_SHA512: memcpy(digests2.sha512, digest, sizeof(digests2.sha512)); break; diff --git a/src/libpakfire/downloader.c b/src/libpakfire/downloader.c index 1fbf33781..6a872c8ad 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_BLAKE2B512: + transfer->md = EVP_blake2b512(); + break; + + case PAKFIRE_DIGEST_BLAKE2S256: + transfer->md = EVP_blake2s256(); + break; + case PAKFIRE_DIGEST_SHA512: transfer->md = EVP_sha512(); break; diff --git a/src/libpakfire/file.c b/src/libpakfire/file.c index 0f439b6b5..cced21ea2 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: BLAKE2b512 + if (strcmp(attr, "PAKFIRE.digests.blake2b512") == 0) { + r = pakfire_file_set_digest(file, PAKFIRE_DIGEST_BLAKE2B512, value, size); + if (r) + goto ERROR; + + // Digest: BLAKE2b512 + } else if (strcmp(attr, "PAKFIRE.digests.blake2s256") == 0) { + r = pakfire_file_set_digest(file, PAKFIRE_DIGEST_BLAKE2S256, value, size); + if (r) + goto ERROR; + // Digest: SHA-512 - if (strcmp(attr, "PAKFIRE.digests.sha512") == 0) { + } else if (strcmp(attr, "PAKFIRE.digests.sha512") == 0) { r = pakfire_file_set_digest(file, PAKFIRE_DIGEST_SHA512, value, size); if (r) goto ERROR; @@ -274,6 +286,16 @@ struct archive_entry* pakfire_file_archive_entry(struct pakfire_file* file) { // Copy digests + // BLAKE2b512 + if (pakfire_digest_set(file->digests.blake2b512)) + archive_entry_xattr_add_entry(entry, "PAKFIRE.digests.blake2b512", + file->digests.blake2b512, sizeof(file->digests.blake2b512)); + + // BLAKE2s256 + if (pakfire_digest_set(file->digests.blake2s256)) + archive_entry_xattr_add_entry(entry, "PAKFIRE.digests.blake2s256", + file->digests.blake2s256, sizeof(file->digests.blake2s256)); + // SHA-512 if (pakfire_digest_set(file->digests.sha512)) archive_entry_xattr_add_entry(entry, "PAKFIRE.digests.sha512", @@ -459,6 +481,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_BLAKE2B512: + if (!pakfire_digest_set(file->digests.blake2b512)) + return NULL; + + if (length) + *length = sizeof(file->digests.blake2b512); + + return file->digests.blake2b512; + + case PAKFIRE_DIGEST_BLAKE2S256: + if (!pakfire_digest_set(file->digests.blake2s256)) + return NULL; + + if (length) + *length = sizeof(file->digests.blake2s256); + + return file->digests.blake2s256; + case PAKFIRE_DIGEST_SHA512: if (!pakfire_digest_set(file->digests.sha512)) return NULL; @@ -500,6 +540,14 @@ PAKFIRE_EXPORT int pakfire_file_set_digest(struct pakfire_file* file, // Store the digest switch (type) { + case PAKFIRE_DIGEST_BLAKE2B512: + memcpy(file->digests.blake2b512, digest, sizeof(file->digests.blake2b512)); + break; + + case PAKFIRE_DIGEST_BLAKE2S256: + memcpy(file->digests.blake2s256, digest, sizeof(file->digests.blake2s256)); + break; + case PAKFIRE_DIGEST_SHA512: memcpy(file->digests.sha512, digest, sizeof(file->digests.sha512)); break; diff --git a/src/libpakfire/include/pakfire/digest.h b/src/libpakfire/include/pakfire/digest.h index 82adb7f11..f059c5ce4 100644 --- a/src/libpakfire/include/pakfire/digest.h +++ b/src/libpakfire/include/pakfire/digest.h @@ -23,12 +23,14 @@ // Pakfire knows these digests enum pakfire_digest_types { - PAKFIRE_DIGEST_UNDEFINED = 0, - PAKFIRE_DIGEST_SHA256 = (1 << 0), - PAKFIRE_DIGEST_SHA512 = (1 << 1), + PAKFIRE_DIGEST_UNDEFINED = 0, + PAKFIRE_DIGEST_SHA256 = (1 << 0), + PAKFIRE_DIGEST_SHA512 = (1 << 1), + PAKFIRE_DIGEST_BLAKE2S256 = (1 << 2), + PAKFIRE_DIGEST_BLAKE2B512 = (1 << 3), }; -#define PAKFIRE_DIGESTS_ALL (PAKFIRE_DIGEST_SHA512 | PAKFIRE_DIGEST_SHA256) +#define PAKFIRE_DIGESTS_ALL (~PAKFIRE_DIGEST_UNDEFINED) #ifdef PAKFIRE_PRIVATE @@ -41,8 +43,23 @@ enum pakfire_digest_types { // libsolv only supports storing one checksum which has to be of a supported type #define PAKFIRE_ARCHIVE_CHECKSUM PAKFIRE_DIGEST_SHA512 +// Define BLAKE2's digest lengths +#ifndef BLAKE2S256_DIGEST_LENGTH +# define BLAKE2S256_DIGEST_LENGTH 32 +#endif /* BLAKE2S256_DIGEST_LENGTH */ + +#ifndef BLAKE2B512_DIGEST_LENGTH +# define BLAKE2B512_DIGEST_LENGTH 64 +#endif /* BLAKE2B512_DIGEST_LENGTH */ + // Digests struct pakfire_digests { + // BLAKE2b512 + unsigned char blake2b512[BLAKE2B512_DIGEST_LENGTH]; + + // BLAKE2s256 + unsigned char blake2s256[BLAKE2S256_DIGEST_LENGTH]; + // SHA-512 unsigned char sha512[SHA512_DIGEST_LENGTH]; @@ -52,6 +69,8 @@ struct pakfire_digests { #define PAKFIRE_DIGESTS_INIT \ { \ + .blake2b512 = 0, \ + .blake2s256 = 0, \ .sha512 = 0, \ .sha256 = 0, \ } diff --git a/src/libpakfire/package.c b/src/libpakfire/package.c index 4d4ca52f6..a9eb3b740 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_BLAKE2B512: + case PAKFIRE_DIGEST_BLAKE2S256: case PAKFIRE_DIGEST_UNDEFINED: break; }