]> git.ipfire.org Git - pakfire.git/commitdiff
digest: Add support for BLAKE2b512/BLAKE2s256
authorMichael Tremer <michael.tremer@ipfire.org>
Wed, 24 Aug 2022 18:02:36 +0000 (18:02 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Wed, 24 Aug 2022 18:02:36 +0000 (18:02 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/libpakfire/digest.c
src/libpakfire/downloader.c
src/libpakfire/file.c
src/libpakfire/include/pakfire/digest.h
src/libpakfire/package.c

index 68100faf369c1df7df6bd7653b20077536078e1e..9cdba02d1aca5e99818c9be4ae52640242774ff4 100644 (file)
 
 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;
index 1fbf337816ebd26380dda5216f0e695975e5a9be..6a872c8add5b6a46dca350c26278aac75c1eaa2f 100644 (file)
@@ -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;
index 0f439b6b572700e2b476ae02dae1d1c237789f87..cced21ea2a8d753986098664b50fa313b1687cf6 100644 (file)
@@ -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;
index 82adb7f112fb7674e667c59d62d8c023aefbecda..f059c5ce498abe3d9abda417924ef9ad6c3a8302 100644 (file)
 
 // 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, \
        }
index 4d4ca52f6e4acf3f373800910e926f5da9d0738f..a9eb3b740df29646dc0d04aaa99fd5f7f8fd21f9 100644 (file)
@@ -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;
                }