/* apk_crypt.c - Alpine Package Keeper (APK) * * Copyright (C) 2021 Timo Teräs * All rights reserved. * * SPDX-License-Identifier: GPL-2.0-only */ #ifndef APK_CRYPTO_H #define APK_CRYPTO_H #include #include "apk_blob.h" #include "apk_defines.h" // Digest struct apk_digest_ctx { uint8_t alg; void *impl; }; #define APK_DIGEST_NONE 0x00 #define APK_DIGEST_MD5 0x01 #define APK_DIGEST_SHA1 0x02 #define APK_DIGEST_SHA256 0x03 #define APK_DIGEST_SHA512 0x04 #define APK_DIGEST_SHA256_160 0x05 #define APK_DIGEST_MAX 0x06 #define APK_DIGEST_MAX_LENGTH 64 // longest is SHA512 #define APK_KEY_VERSION_V2 0x00 #define APK_KEY_VERSION_CUTE 0x01 #define APK_KEY_VERSION_MAX 0x02 #define APK_SIGNATURE_RSA 0x00 #define APK_SIGNATURE_RSA512 0x01 #define APK_SIGNATURE_RSA256 0x02 #define APK_SIGNATURE_CUTE 0x03 #define APK_SIGNATURE_MAX 0x04 const char *apk_digest_alg_str(uint8_t alg); uint8_t apk_digest_alg_from_csum(int csum); struct apk_digest { uint8_t alg; uint8_t len; uint8_t data[APK_DIGEST_MAX_LENGTH]; }; #define APK_DIGEST_BLOB(d) APK_BLOB_PTR_LEN((void *) ((d).data), (d).len) int apk_digest_alg_len(uint8_t alg); uint8_t apk_digest_alg_by_len(int len); static inline int apk_digest_cmp(struct apk_digest *a, struct apk_digest *b) { if (a->alg != b->alg) return b->alg - a->alg; return memcmp(a->data, b->data, a->len); } static inline void apk_digest_reset(struct apk_digest *d) { d->alg = APK_DIGEST_NONE; d->len = 0; } static inline void apk_digest_set(struct apk_digest *d, uint8_t alg) { d->alg = alg; d->len = apk_digest_alg_len(alg); } int apk_digest_calc(struct apk_digest *d, uint8_t alg, const void *ptr, size_t sz); int apk_digest_ctx_init(struct apk_digest_ctx *dctx, uint8_t alg); int apk_digest_ctx_reset(struct apk_digest_ctx *dctx, uint8_t alg); void apk_digest_ctx_free(struct apk_digest_ctx *dctx); int apk_digest_ctx_update(struct apk_digest_ctx *dctx, const void *ptr, size_t sz); int apk_digest_ctx_final(struct apk_digest_ctx *dctx, struct apk_digest *d); uint8_t apk_digest_from_blob(struct apk_digest *d, apk_blob_t b); static inline int apk_digest_cmp_csum(const struct apk_digest *d, const struct apk_checksum *csum) { return apk_blob_compare(APK_DIGEST_BLOB(*d), APK_BLOB_CSUM(*csum)); } static inline void apk_checksum_from_digest(struct apk_checksum *csum, const struct apk_digest *d) { if (d->len > sizeof csum->data) { csum->type = APK_CHECKSUM_NONE; } else { csum->type = d->len; memcpy(csum->data, d->data, d->len); } } // Asymmetric keys struct apk_public_key { uint16_t version; uint8_t id[16]; void *impl; }; struct apk_secret_key { uint16_t version; uint8_t id[16]; void *impl; }; int apk_public_key_load(struct apk_public_key *pub, int dirfd, const char *fn); void apk_public_key_free(struct apk_public_key *pub); int apk_secret_key_load(struct apk_secret_key *sec, int dirfd, const char *fn); void apk_secret_key_free(struct apk_secret_key *sec); // Signing int apk_sign_digest_start(struct apk_digest_ctx *dctx, uint16_t version); int apk_sign(struct apk_secret_key *sec, struct apk_digest_ctx *dctx, void *sig, size_t *len); int apk_verify_digest_start(struct apk_digest_ctx *dctx, uint16_t version); int apk_verify(struct apk_public_key *pub, struct apk_digest_ctx *dctx, void *sig, size_t len); // Initializiation int apk_crypto_init(void); #endif