+typedef void (*cs_md_init)(void *ctx);
+typedef void (*cs_md_update)(void *ctx, const void *data, size_t size);
+typedef void (*cs_md_final)(void *hash, void *ctx);
+
+struct cs_hash {
+ uint8_t cs_type; /* type code as per code signing */
+ size_t cs_size; /* size of effective hash (may be truncated) */
+ size_t cs_digest_size; /* size of native hash */
+ cs_md_init cs_init;
+ cs_md_update cs_update;
+ cs_md_final cs_final;
+};
+
+static struct cs_hash cs_hash_sha1 = {
+ .cs_type = CS_HASHTYPE_SHA1,
+ .cs_size = CS_SHA1_LEN,
+ .cs_digest_size = SHA_DIGEST_LENGTH,
+ .cs_init = (cs_md_init)SHA1Init,
+ .cs_update = (cs_md_update)SHA1Update,
+ .cs_final = (cs_md_final)SHA1Final,
+};
+#if CRYPTO_SHA2
+static struct cs_hash cs_hash_sha256 = {
+ .cs_type = CS_HASHTYPE_SHA256,
+ .cs_size = SHA256_DIGEST_LENGTH,
+ .cs_digest_size = SHA256_DIGEST_LENGTH,
+ .cs_init = (cs_md_init)SHA256_Init,
+ .cs_update = (cs_md_update)SHA256_Update,
+ .cs_final = (cs_md_final)SHA256_Final,
+};
+static struct cs_hash cs_hash_sha256_truncate = {
+ .cs_type = CS_HASHTYPE_SHA256_TRUNCATED,
+ .cs_size = CS_SHA256_TRUNCATED_LEN,
+ .cs_digest_size = SHA256_DIGEST_LENGTH,
+ .cs_init = (cs_md_init)SHA256_Init,
+ .cs_update = (cs_md_update)SHA256_Update,
+ .cs_final = (cs_md_final)SHA256_Final,
+};
+static struct cs_hash cs_hash_sha384 = {
+ .cs_type = CS_HASHTYPE_SHA384,
+ .cs_size = SHA384_DIGEST_LENGTH,
+ .cs_digest_size = SHA384_DIGEST_LENGTH,
+ .cs_init = (cs_md_init)SHA384_Init,
+ .cs_update = (cs_md_update)SHA384_Update,
+ .cs_final = (cs_md_final)SHA384_Final,
+};
+#endif
+
+static struct cs_hash *
+cs_find_md(uint8_t type)
+{
+ if (type == CS_HASHTYPE_SHA1) {
+ return &cs_hash_sha1;
+#if CRYPTO_SHA2
+ } else if (type == CS_HASHTYPE_SHA256) {
+ return &cs_hash_sha256;
+ } else if (type == CS_HASHTYPE_SHA256_TRUNCATED) {
+ return &cs_hash_sha256_truncate;
+ } else if (type == CS_HASHTYPE_SHA384) {
+ return &cs_hash_sha384;
+#endif
+ }
+ return NULL;
+}