apk-tools/src/apk_crypto.h

134 lines
3.4 KiB
C

/* apk_crypt.c - Alpine Package Keeper (APK)
*
* Copyright (C) 2021 Timo Teräs <timo.teras@iki.fi>
* All rights reserved.
*
* SPDX-License-Identifier: GPL-2.0-only
*/
#ifndef APK_CRYPTO_H
#define APK_CRYPTO_H
#include <string.h>
#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