1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * fs-verity hash algorithms 4 * 5 * Copyright (C) 2018 Google LLC 6 * 7 * Written by Eric Biggers. 8 */ 9 10 #include <openssl/evp.h> 11 #include <stdlib.h> 12 #include <string.h> 13 14 #include "fsverity_uapi.h" 15 #include "hash_algs.h" 16 17 static void free_hash_ctx(struct hash_ctx *ctx) 18 { 19 free(ctx); 20 } 21 22 /* ========== libcrypto (OpenSSL) wrappers ========== */ 23 24 struct openssl_hash_ctx { 25 struct hash_ctx base; /* must be first */ 26 EVP_MD_CTX *md_ctx; 27 const EVP_MD *md; 28 }; 29 30 static void openssl_digest_init(struct hash_ctx *_ctx) 31 { 32 struct openssl_hash_ctx *ctx = (void *)_ctx; 33 34 if (EVP_DigestInit_ex(ctx->md_ctx, ctx->md, NULL) != 1) 35 fatal_error("EVP_DigestInit_ex() failed for algorithm '%s'", 36 ctx->base.alg->name); 37 } 38 39 static void openssl_digest_update(struct hash_ctx *_ctx, 40 const void *data, size_t size) 41 { 42 struct openssl_hash_ctx *ctx = (void *)_ctx; 43 44 if (EVP_DigestUpdate(ctx->md_ctx, data, size) != 1) 45 fatal_error("EVP_DigestUpdate() failed for algorithm '%s'", 46 ctx->base.alg->name); 47 } 48 49 static void openssl_digest_final(struct hash_ctx *_ctx, u8 *digest) 50 { 51 struct openssl_hash_ctx *ctx = (void *)_ctx; 52 53 if (EVP_DigestFinal_ex(ctx->md_ctx, digest, NULL) != 1) 54 fatal_error("EVP_DigestFinal_ex() failed for algorithm '%s'", 55 ctx->base.alg->name); 56 } 57 58 static void openssl_digest_ctx_free(struct hash_ctx *_ctx) 59 { 60 struct openssl_hash_ctx *ctx = (void *)_ctx; 61 62 /* 63 * OpenSSL 1.1.0 renamed EVP_MD_CTX_destroy() to EVP_MD_CTX_free() but 64 * kept the old name as a macro. Use the old name for compatibility 65 * with older OpenSSL versions. 66 */ 67 EVP_MD_CTX_destroy(ctx->md_ctx); 68 free(ctx); 69 } 70 71 static struct hash_ctx * 72 openssl_digest_ctx_create(const struct fsverity_hash_alg *alg, const EVP_MD *md) 73 { 74 struct openssl_hash_ctx *ctx; 75 76 ctx = xzalloc(sizeof(*ctx)); 77 ctx->base.alg = alg; 78 ctx->base.init = openssl_digest_init; 79 ctx->base.update = openssl_digest_update; 80 ctx->base.final = openssl_digest_final; 81 ctx->base.free = openssl_digest_ctx_free; 82 /* 83 * OpenSSL 1.1.0 renamed EVP_MD_CTX_create() to EVP_MD_CTX_new() but 84 * kept the old name as a macro. Use the old name for compatibility 85 * with older OpenSSL versions. 86 */ 87 ctx->md_ctx = EVP_MD_CTX_create(); 88 if (!ctx->md_ctx) 89 fatal_error("out of memory"); 90 91 ctx->md = md; 92 ASSERT(EVP_MD_size(md) == alg->digest_size); 93 94 return &ctx->base; 95 } 96 97 static struct hash_ctx *create_sha256_ctx(const struct fsverity_hash_alg *alg) 98 { 99 return openssl_digest_ctx_create(alg, EVP_sha256()); 100 } 101 102 static struct hash_ctx *create_sha512_ctx(const struct fsverity_hash_alg *alg) 103 { 104 return openssl_digest_ctx_create(alg, EVP_sha512()); 105 } 106 107 /* ========== CRC-32C ========== */ 108 109 /* 110 * There are faster ways to calculate CRC's, but for now we just use the 111 * 256-entry table method as it's portable and not too complex. 112 */ 113 114 #include "crc32c_table.h" 115 116 struct crc32c_hash_ctx { 117 struct hash_ctx base; /* must be first */ 118 u32 remainder; 119 }; 120 121 static void crc32c_init(struct hash_ctx *_ctx) 122 { 123 struct crc32c_hash_ctx *ctx = (void *)_ctx; 124 125 ctx->remainder = ~0; 126 } 127 128 static void crc32c_update(struct hash_ctx *_ctx, const void *data, size_t size) 129 { 130 struct crc32c_hash_ctx *ctx = (void *)_ctx; 131 const u8 *p = data; 132 u32 r = ctx->remainder; 133 134 while (size--) 135 r = (r >> 8) ^ crc32c_table[(u8)r ^ *p++]; 136 137 ctx->remainder = r; 138 } 139 140 static void crc32c_final(struct hash_ctx *_ctx, u8 *digest) 141 { 142 struct crc32c_hash_ctx *ctx = (void *)_ctx; 143 __le32 remainder = cpu_to_le32(~ctx->remainder); 144 145 memcpy(digest, &remainder, sizeof(remainder)); 146 } 147 148 static struct hash_ctx *create_crc32c_ctx(const struct fsverity_hash_alg *alg) 149 { 150 struct crc32c_hash_ctx *ctx = xzalloc(sizeof(*ctx)); 151 152 ctx->base.alg = alg; 153 ctx->base.init = crc32c_init; 154 ctx->base.update = crc32c_update; 155 ctx->base.final = crc32c_final; 156 ctx->base.free = free_hash_ctx; 157 return &ctx->base; 158 } 159 160 /* ========== Hash algorithm definitions ========== */ 161 162 const struct fsverity_hash_alg fsverity_hash_algs[] = { 163 [FS_VERITY_ALG_SHA256] = { 164 .name = "sha256", 165 .digest_size = 32, 166 .cryptographic = true, 167 .create_ctx = create_sha256_ctx, 168 }, 169 [FS_VERITY_ALG_SHA512] = { 170 .name = "sha512", 171 .digest_size = 64, 172 .cryptographic = true, 173 .create_ctx = create_sha512_ctx, 174 }, 175 [FS_VERITY_ALG_CRC32C] = { 176 .name = "crc32c", 177 .digest_size = 4, 178 .create_ctx = create_crc32c_ctx, 179 }, 180 }; 181 182 const struct fsverity_hash_alg *find_hash_alg_by_name(const char *name) 183 { 184 int i; 185 186 for (i = 0; i < ARRAY_SIZE(fsverity_hash_algs); i++) { 187 if (fsverity_hash_algs[i].name && 188 !strcmp(name, fsverity_hash_algs[i].name)) 189 return &fsverity_hash_algs[i]; 190 } 191 error_msg("unknown hash algorithm: '%s'", name); 192 fputs("Available hash algorithms: ", stderr); 193 show_all_hash_algs(stderr); 194 putc('\n', stderr); 195 return NULL; 196 } 197 198 const struct fsverity_hash_alg *find_hash_alg_by_num(unsigned int num) 199 { 200 if (num < ARRAY_SIZE(fsverity_hash_algs) && 201 fsverity_hash_algs[num].name) 202 return &fsverity_hash_algs[num]; 203 204 return NULL; 205 } 206 207 void show_all_hash_algs(FILE *fp) 208 { 209 int i; 210 const char *sep = ""; 211 212 for (i = 0; i < ARRAY_SIZE(fsverity_hash_algs); i++) { 213 if (fsverity_hash_algs[i].name) { 214 fprintf(fp, "%s%s", sep, fsverity_hash_algs[i].name); 215 sep = ", "; 216 } 217 } 218 } 219