commit 3f81ccbdc1260ec6bd1465a10f6cc3a530a991b3 from: Omar Polo date: Sun Feb 12 11:16:23 2023 UTC add functions to compute hashes This adds a set of functions to abstract over SHA1Init, SHA1Update, SHA1Final, their respective SHA256 variants and how to compare digests. It's a preparatory step for sha256 pack handling. commit - 0be5386d2f5cb3b62d4c63218734063b97053417 commit + 3f81ccbdc1260ec6bd1465a10f6cc3a530a991b3 blob - 7672f9da04d627c9c0d625a0aeafe03183f72626 blob + 7941cebcee734db2de13f407678a3b740f02ca32 --- include/got_object.h +++ include/got_object.h @@ -14,6 +14,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#define GOT_OBJECT_ID_MAXLEN SHA256_DIGEST_LENGTH #define GOT_OBJECT_ID_HEX_MAXLEN SHA1_DIGEST_STRING_LENGTH enum got_hash_algorithm { blob - 1be2c114d68240daa41c9b9ac210889da06b42f5 blob + c70734016d6453f21cfe4275495824160a6b0fd2 --- lib/got_lib_hash.h +++ lib/got_lib_hash.h @@ -26,3 +26,22 @@ int got_parse_sha256_digest(uint8_t *, const char *); char *got_sha256_digest_to_str(const uint8_t *, char *, size_t); int got_parse_hash_digest(uint8_t *, const char *, enum got_hash_algorithm); + +struct got_hash { + SHA1_CTX sha1_ctx; + SHA2_CTX sha256_ctx; + enum got_hash_algorithm algo; +}; + +/* + * These functions allow to compute and check hashes. + * The hash function used is specified during got_hash_init. + * Data can be added with got_hash_update and, once done, the checksum + * can be obtained with got_hash_final; its output buffer must be at + * least GOT_OBJECT_ID_MAXLEN bytes. + * got_hash_cmp is like memcmp() and compares two hash digests. + */ +void got_hash_init(struct got_hash *, enum got_hash_algorithm); +void got_hash_update(struct got_hash *, const void *, size_t); +void got_hash_final(struct got_hash *, uint8_t *); +int got_hash_cmp(struct got_hash *, uint8_t *, uint8_t *); blob - 12bba1c67ab7760ff6e537cfc5be4af481afd7ee blob + 21a5c5b28f97a2360115141697b94ec051b7d467 --- lib/hash.c +++ lib/hash.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include "got_object.h" @@ -144,3 +145,43 @@ got_parse_hash_digest(uint8_t *digest, const char *lin return 0; } } + +void +got_hash_init(struct got_hash *hash, enum got_hash_algorithm algo) +{ + memset(hash, 0, sizeof(*hash)); + hash->algo = algo; + + if (algo == GOT_HASH_SHA1) + SHA1Init(&hash->sha1_ctx); + else if (algo == GOT_HASH_SHA256) + SHA256Init(&hash->sha256_ctx); +} + +void +got_hash_update(struct got_hash *hash, const void *data, size_t len) +{ + if (hash->algo == GOT_HASH_SHA1) + SHA1Update(&hash->sha1_ctx, data, len); + else if (hash->algo == GOT_HASH_SHA256) + SHA256Update(&hash->sha256_ctx, data, len); +} + +void +got_hash_final(struct got_hash *hash, uint8_t *out) +{ + if (hash->algo == GOT_HASH_SHA1) + SHA1Final(out, &hash->sha1_ctx); + else if (hash->algo == GOT_HASH_SHA256) + SHA256Final(out, &hash->sha256_ctx); +} + +int +got_hash_cmp(struct got_hash *hash, uint8_t *orig, uint8_t *target) +{ + if (hash->algo == GOT_HASH_SHA1) + return memcmp(orig, target, SHA1_DIGEST_LENGTH); + else if (hash->algo == GOT_HASH_SHA256) + return memcmp(orig, target, SHA256_DIGEST_LENGTH); + return -1; +} blob - d520044fc04a93dd4f53e69a52edbdca55554921 blob + 2a89d71d16ccc445d75c986691f8a7d73085ab30 --- lib/pack.c +++ lib/pack.c @@ -74,14 +74,15 @@ const struct got_error * got_packidx_init_hdr(struct got_packidx *p, int verify, off_t packfile_size) { const struct got_error *err = NULL; + enum got_hash_algorithm algo = GOT_HASH_SHA1; struct got_packidx_v2_hdr *h; - SHA1_CTX ctx; - uint8_t sha1[SHA1_DIGEST_LENGTH]; + struct got_hash ctx; + uint8_t hash[GOT_OBJECT_ID_MAXLEN]; size_t nobj, len_fanout, len_ids, offset, remain; ssize_t n; int i; - SHA1Init(&ctx); + got_hash_init(&ctx, algo); h = &p->hdr; offset = 0; @@ -116,7 +117,7 @@ got_packidx_init_hdr(struct got_packidx *p, int verify remain -= sizeof(*h->magic); if (verify) - SHA1Update(&ctx, (uint8_t *)h->magic, sizeof(*h->magic)); + got_hash_update(&ctx, h->magic, sizeof(*h->magic)); if (remain < sizeof(*h->version)) { err = got_error(GOT_ERR_BAD_PACKIDX); @@ -147,7 +148,7 @@ got_packidx_init_hdr(struct got_packidx *p, int verify remain -= sizeof(*h->version); if (verify) - SHA1Update(&ctx, (uint8_t *)h->version, sizeof(*h->version)); + got_hash_update(&ctx, h->version, sizeof(*h->version)); len_fanout = sizeof(*h->fanout_table) * GOT_PACKIDX_V2_FANOUT_TABLE_ITEMS; @@ -176,7 +177,7 @@ got_packidx_init_hdr(struct got_packidx *p, int verify if (err) goto done; if (verify) - SHA1Update(&ctx, (uint8_t *)h->fanout_table, len_fanout); + got_hash_update(&ctx, h->fanout_table, len_fanout); offset += len_fanout; remain -= len_fanout; @@ -204,7 +205,7 @@ got_packidx_init_hdr(struct got_packidx *p, int verify } } if (verify) - SHA1Update(&ctx, (uint8_t *)h->sorted_ids, len_ids); + got_hash_update(&ctx, h->sorted_ids, len_ids); offset += len_ids; remain -= len_ids; @@ -229,7 +230,7 @@ got_packidx_init_hdr(struct got_packidx *p, int verify } } if (verify) - SHA1Update(&ctx, (uint8_t *)h->crc32, nobj * sizeof(*h->crc32)); + got_hash_update(&ctx, h->crc32, nobj * sizeof(*h->crc32)); remain -= nobj * sizeof(*h->crc32); offset += nobj * sizeof(*h->crc32); @@ -254,8 +255,7 @@ got_packidx_init_hdr(struct got_packidx *p, int verify } } if (verify) - SHA1Update(&ctx, (uint8_t *)h->offsets, - nobj * sizeof(*h->offsets)); + got_hash_update(&ctx, h->offsets, nobj * sizeof(*h->offsets)); remain -= nobj * sizeof(*h->offsets); offset += nobj * sizeof(*h->offsets); @@ -297,7 +297,7 @@ got_packidx_init_hdr(struct got_packidx *p, int verify } } if (verify) - SHA1Update(&ctx, (uint8_t*)h->large_offsets, + got_hash_update(&ctx, h->large_offsets, p->nlargeobj * sizeof(*h->large_offsets)); remain -= p->nlargeobj * sizeof(*h->large_offsets); offset += p->nlargeobj * sizeof(*h->large_offsets); @@ -325,10 +325,10 @@ checksum: } } if (verify) { - SHA1Update(&ctx, h->trailer->packfile_sha1, SHA1_DIGEST_LENGTH); - SHA1Final(sha1, &ctx); - if (memcmp(h->trailer->packidx_sha1, sha1, - SHA1_DIGEST_LENGTH) != 0) + got_hash_update(&ctx, h->trailer->packfile_sha1, + SHA1_DIGEST_LENGTH); + got_hash_final(&ctx, hash); + if (got_hash_cmp(&ctx, hash, h->trailer->packidx_sha1) != 0) err = got_error(GOT_ERR_PACKIDX_CSUM); } done: