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;
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());
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);
}
}
+ // 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);
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)
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));
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;
// 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;
// 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;
// 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",
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;
// 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;
// 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
// 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];
#define PAKFIRE_DIGESTS_INIT \
{ \
+ .blake2b512 = 0, \
+ .blake2s256 = 0, \
.sha512 = 0, \
.sha256 = 0, \
}
pakfire_package_dump_add_line(&string, _("SHA256 Digest"), hexdigest);
break;
+ case PAKFIRE_DIGEST_BLAKE2B512:
+ case PAKFIRE_DIGEST_BLAKE2S256:
case PAKFIRE_DIGEST_UNDEFINED:
break;
}