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) 20 static_assert(sizeof(struct md5_ctx) == sizeof(struct md5_state)); 21 static_assert(offsetof(struct md5_ctx, state) == offsetof(struct md5_state, hash)); 22 static_assert(offsetof(struct md5_ctx, bytecount) == offsetof(struct md5_state, byte_count)); 23 static_assert(offsetof(struct md5_ctx, buf) == offsetof(struct md5_state, block)); 24 25 static 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 39 static 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 49 static 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 55 static 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 61 const 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 }; 65 EXPORT_SYMBOL_GPL(md5_zero_message_hash); 66 67 #define MD5_CTX(desc) ((struct md5_ctx *)shash_desc_ctx(desc)) 68 69 static int crypto_md5_init(struct shash_desc *desc) 70 { 71 md5_init(MD5_CTX(desc)); 72 return 0; 73 } 74 75 static 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 82 static int crypto_md5_final(struct shash_desc *desc, u8 *out) 83 { 84 md5_final(MD5_CTX(desc), out); 85 return 0; 86 } 87 88 static 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 95 static int crypto_md5_export(struct shash_desc *desc, void *out) 96 { 97 return __crypto_md5_export(MD5_CTX(desc), out); 98 } 99 100 static int crypto_md5_import(struct shash_desc *desc, const void *in) 101 { 102 return __crypto_md5_import(MD5_CTX(desc), in); 103 } 104 105 static int crypto_md5_export_core(struct shash_desc *desc, void *out) 106 { 107 return __crypto_md5_export_core(MD5_CTX(desc), out); 108 } 109 110 static 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 118 static 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 125 static 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 131 static 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 138 static 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 144 static 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 151 static 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 156 static 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 164 static 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 169 static 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 177 static 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 218 static int __init crypto_md5_mod_init(void) 219 { 220 return crypto_register_shashes(algs, ARRAY_SIZE(algs)); 221 } 222 module_init(crypto_md5_mod_init); 223 224 static void __exit crypto_md5_mod_exit(void) 225 { 226 crypto_unregister_shashes(algs, ARRAY_SIZE(algs)); 227 } 228 module_exit(crypto_md5_mod_exit); 229 230 MODULE_LICENSE("GPL"); 231 MODULE_DESCRIPTION("Crypto API support for MD5 and HMAC-MD5"); 232 233 MODULE_ALIAS_CRYPTO("md5"); 234 MODULE_ALIAS_CRYPTO("md5-lib"); 235 MODULE_ALIAS_CRYPTO("hmac(md5)"); 236 MODULE_ALIAS_CRYPTO("hmac-md5-lib"); 237