at master 6.4 kB view raw
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * Crypto API support for MD5 and HMAC-MD5 4 * 5 * Copyright 2025 Google LLC 6 */ 7#include <crypto/internal/hash.h> 8#include <crypto/md5.h> 9#include <linux/kernel.h> 10#include <linux/module.h> 11 12/* 13 * Export and import functions. crypto_shash wants a particular format that 14 * matches that used by some legacy drivers. It currently is the same as the 15 * library MD5 context, except the value in bytecount must be block-aligned and 16 * the remainder must be stored in an extra u8 appended to the struct. 17 */ 18 19#define MD5_SHASH_STATE_SIZE (sizeof(struct md5_ctx) + 1) 20static_assert(sizeof(struct md5_ctx) == sizeof(struct md5_state)); 21static_assert(offsetof(struct md5_ctx, state) == offsetof(struct md5_state, hash)); 22static_assert(offsetof(struct md5_ctx, bytecount) == offsetof(struct md5_state, byte_count)); 23static_assert(offsetof(struct md5_ctx, buf) == offsetof(struct md5_state, block)); 24 25static int __crypto_md5_export(const struct md5_ctx *ctx0, void *out) 26{ 27 struct md5_ctx ctx = *ctx0; 28 unsigned int partial; 29 u8 *p = out; 30 31 partial = ctx.bytecount % MD5_BLOCK_SIZE; 32 ctx.bytecount -= partial; 33 memcpy(p, &ctx, sizeof(ctx)); 34 p += sizeof(ctx); 35 *p = partial; 36 return 0; 37} 38 39static int __crypto_md5_import(struct md5_ctx *ctx, const void *in) 40{ 41 const u8 *p = in; 42 43 memcpy(ctx, p, sizeof(*ctx)); 44 p += sizeof(*ctx); 45 ctx->bytecount += *p; 46 return 0; 47} 48 49static int __crypto_md5_export_core(const struct md5_ctx *ctx, void *out) 50{ 51 memcpy(out, ctx, offsetof(struct md5_ctx, buf)); 52 return 0; 53} 54 55static int __crypto_md5_import_core(struct md5_ctx *ctx, const void *in) 56{ 57 memcpy(ctx, in, offsetof(struct md5_ctx, buf)); 58 return 0; 59} 60 61const u8 md5_zero_message_hash[MD5_DIGEST_SIZE] = { 62 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04, 63 0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e, 64}; 65EXPORT_SYMBOL_GPL(md5_zero_message_hash); 66 67#define MD5_CTX(desc) ((struct md5_ctx *)shash_desc_ctx(desc)) 68 69static int crypto_md5_init(struct shash_desc *desc) 70{ 71 md5_init(MD5_CTX(desc)); 72 return 0; 73} 74 75static int crypto_md5_update(struct shash_desc *desc, 76 const u8 *data, unsigned int len) 77{ 78 md5_update(MD5_CTX(desc), data, len); 79 return 0; 80} 81 82static int crypto_md5_final(struct shash_desc *desc, u8 *out) 83{ 84 md5_final(MD5_CTX(desc), out); 85 return 0; 86} 87 88static int crypto_md5_digest(struct shash_desc *desc, 89 const u8 *data, unsigned int len, u8 *out) 90{ 91 md5(data, len, out); 92 return 0; 93} 94 95static int crypto_md5_export(struct shash_desc *desc, void *out) 96{ 97 return __crypto_md5_export(MD5_CTX(desc), out); 98} 99 100static int crypto_md5_import(struct shash_desc *desc, const void *in) 101{ 102 return __crypto_md5_import(MD5_CTX(desc), in); 103} 104 105static int crypto_md5_export_core(struct shash_desc *desc, void *out) 106{ 107 return __crypto_md5_export_core(MD5_CTX(desc), out); 108} 109 110static int crypto_md5_import_core(struct shash_desc *desc, const void *in) 111{ 112 return __crypto_md5_import_core(MD5_CTX(desc), in); 113} 114 115#define HMAC_MD5_KEY(tfm) ((struct hmac_md5_key *)crypto_shash_ctx(tfm)) 116#define HMAC_MD5_CTX(desc) ((struct hmac_md5_ctx *)shash_desc_ctx(desc)) 117 118static int crypto_hmac_md5_setkey(struct crypto_shash *tfm, 119 const u8 *raw_key, unsigned int keylen) 120{ 121 hmac_md5_preparekey(HMAC_MD5_KEY(tfm), raw_key, keylen); 122 return 0; 123} 124 125static int crypto_hmac_md5_init(struct shash_desc *desc) 126{ 127 hmac_md5_init(HMAC_MD5_CTX(desc), HMAC_MD5_KEY(desc->tfm)); 128 return 0; 129} 130 131static int crypto_hmac_md5_update(struct shash_desc *desc, 132 const u8 *data, unsigned int len) 133{ 134 hmac_md5_update(HMAC_MD5_CTX(desc), data, len); 135 return 0; 136} 137 138static int crypto_hmac_md5_final(struct shash_desc *desc, u8 *out) 139{ 140 hmac_md5_final(HMAC_MD5_CTX(desc), out); 141 return 0; 142} 143 144static int crypto_hmac_md5_digest(struct shash_desc *desc, 145 const u8 *data, unsigned int len, u8 *out) 146{ 147 hmac_md5(HMAC_MD5_KEY(desc->tfm), data, len, out); 148 return 0; 149} 150 151static int crypto_hmac_md5_export(struct shash_desc *desc, void *out) 152{ 153 return __crypto_md5_export(&HMAC_MD5_CTX(desc)->hash_ctx, out); 154} 155 156static int crypto_hmac_md5_import(struct shash_desc *desc, const void *in) 157{ 158 struct hmac_md5_ctx *ctx = HMAC_MD5_CTX(desc); 159 160 ctx->ostate = HMAC_MD5_KEY(desc->tfm)->ostate; 161 return __crypto_md5_import(&ctx->hash_ctx, in); 162} 163 164static int crypto_hmac_md5_export_core(struct shash_desc *desc, void *out) 165{ 166 return __crypto_md5_export_core(&HMAC_MD5_CTX(desc)->hash_ctx, out); 167} 168 169static int crypto_hmac_md5_import_core(struct shash_desc *desc, const void *in) 170{ 171 struct hmac_md5_ctx *ctx = HMAC_MD5_CTX(desc); 172 173 ctx->ostate = HMAC_MD5_KEY(desc->tfm)->ostate; 174 return __crypto_md5_import_core(&ctx->hash_ctx, in); 175} 176 177static struct shash_alg algs[] = { 178 { 179 .base.cra_name = "md5", 180 .base.cra_driver_name = "md5-lib", 181 .base.cra_priority = 300, 182 .base.cra_blocksize = MD5_BLOCK_SIZE, 183 .base.cra_module = THIS_MODULE, 184 .digestsize = MD5_DIGEST_SIZE, 185 .init = crypto_md5_init, 186 .update = crypto_md5_update, 187 .final = crypto_md5_final, 188 .digest = crypto_md5_digest, 189 .export = crypto_md5_export, 190 .import = crypto_md5_import, 191 .export_core = crypto_md5_export_core, 192 .import_core = crypto_md5_import_core, 193 .descsize = sizeof(struct md5_ctx), 194 .statesize = MD5_SHASH_STATE_SIZE, 195 }, 196 { 197 .base.cra_name = "hmac(md5)", 198 .base.cra_driver_name = "hmac-md5-lib", 199 .base.cra_priority = 300, 200 .base.cra_blocksize = MD5_BLOCK_SIZE, 201 .base.cra_ctxsize = sizeof(struct hmac_md5_key), 202 .base.cra_module = THIS_MODULE, 203 .digestsize = MD5_DIGEST_SIZE, 204 .setkey = crypto_hmac_md5_setkey, 205 .init = crypto_hmac_md5_init, 206 .update = crypto_hmac_md5_update, 207 .final = crypto_hmac_md5_final, 208 .digest = crypto_hmac_md5_digest, 209 .export = crypto_hmac_md5_export, 210 .import = crypto_hmac_md5_import, 211 .export_core = crypto_hmac_md5_export_core, 212 .import_core = crypto_hmac_md5_import_core, 213 .descsize = sizeof(struct hmac_md5_ctx), 214 .statesize = MD5_SHASH_STATE_SIZE, 215 }, 216}; 217 218static int __init crypto_md5_mod_init(void) 219{ 220 return crypto_register_shashes(algs, ARRAY_SIZE(algs)); 221} 222module_init(crypto_md5_mod_init); 223 224static void __exit crypto_md5_mod_exit(void) 225{ 226 crypto_unregister_shashes(algs, ARRAY_SIZE(algs)); 227} 228module_exit(crypto_md5_mod_exit); 229 230MODULE_LICENSE("GPL"); 231MODULE_DESCRIPTION("Crypto API support for MD5 and HMAC-MD5"); 232 233MODULE_ALIAS_CRYPTO("md5"); 234MODULE_ALIAS_CRYPTO("md5-lib"); 235MODULE_ALIAS_CRYPTO("hmac(md5)"); 236MODULE_ALIAS_CRYPTO("hmac-md5-lib");