1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209
|
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _CRYPTO_MD5_H
#define _CRYPTO_MD5_H
#include <crypto/hash.h>
#include <linux/types.h>
#define MD5_DIGEST_SIZE 16
#define MD5_HMAC_BLOCK_SIZE 64
#define MD5_BLOCK_SIZE 64
#define MD5_BLOCK_WORDS 16
#define MD5_HASH_WORDS 4
#define MD5_STATE_SIZE 24
#define MD5_H0 0x67452301UL
#define MD5_H1 0xefcdab89UL
#define MD5_H2 0x98badcfeUL
#define MD5_H3 0x10325476UL
#define CRYPTO_MD5_STATESIZE \
CRYPTO_HASH_STATESIZE(MD5_STATE_SIZE, MD5_HMAC_BLOCK_SIZE)
extern const u8 md5_zero_message_hash[MD5_DIGEST_SIZE];
struct md5_state {
u32 hash[MD5_HASH_WORDS];
u64 byte_count;
u32 block[MD5_BLOCK_WORDS];
};
/* State for the MD5 compression function */
struct md5_block_state {
u32 h[MD5_HASH_WORDS];
};
/**
* struct md5_ctx - Context for hashing a message with MD5
* @state: the compression function state
* @bytecount: number of bytes processed so far
* @buf: partial block buffer; bytecount % MD5_BLOCK_SIZE bytes are valid
*/
struct md5_ctx {
struct md5_block_state state;
u64 bytecount;
u8 buf[MD5_BLOCK_SIZE] __aligned(__alignof__(__le64));
};
/**
* md5_init() - Initialize an MD5 context for a new message
* @ctx: the context to initialize
*
* If you don't need incremental computation, consider md5() instead.
*
* Context: Any context.
*/
void md5_init(struct md5_ctx *ctx);
/**
* md5_update() - Update an MD5 context with message data
* @ctx: the context to update; must have been initialized
* @data: the message data
* @len: the data length in bytes
*
* This can be called any number of times.
*
* Context: Any context.
*/
void md5_update(struct md5_ctx *ctx, const u8 *data, size_t len);
/**
* md5_final() - Finish computing an MD5 message digest
* @ctx: the context to finalize; must have been initialized
* @out: (output) the resulting MD5 message digest
*
* After finishing, this zeroizes @ctx. So the caller does not need to do it.
*
* Context: Any context.
*/
void md5_final(struct md5_ctx *ctx, u8 out[MD5_DIGEST_SIZE]);
/**
* md5() - Compute MD5 message digest in one shot
* @data: the message data
* @len: the data length in bytes
* @out: (output) the resulting MD5 message digest
*
* Context: Any context.
*/
void md5(const u8 *data, size_t len, u8 out[MD5_DIGEST_SIZE]);
/**
* struct hmac_md5_key - Prepared key for HMAC-MD5
* @istate: private
* @ostate: private
*/
struct hmac_md5_key {
struct md5_block_state istate;
struct md5_block_state ostate;
};
/**
* struct hmac_md5_ctx - Context for computing HMAC-MD5 of a message
* @hash_ctx: private
* @ostate: private
*/
struct hmac_md5_ctx {
struct md5_ctx hash_ctx;
struct md5_block_state ostate;
};
/**
* hmac_md5_preparekey() - Prepare a key for HMAC-MD5
* @key: (output) the key structure to initialize
* @raw_key: the raw HMAC-MD5 key
* @raw_key_len: the key length in bytes. All key lengths are supported.
*
* Note: the caller is responsible for zeroizing both the struct hmac_md5_key
* and the raw key once they are no longer needed.
*
* Context: Any context.
*/
void hmac_md5_preparekey(struct hmac_md5_key *key,
const u8 *raw_key, size_t raw_key_len);
/**
* hmac_md5_init() - Initialize an HMAC-MD5 context for a new message
* @ctx: (output) the HMAC context to initialize
* @key: the prepared HMAC key
*
* If you don't need incremental computation, consider hmac_md5() instead.
*
* Context: Any context.
*/
void hmac_md5_init(struct hmac_md5_ctx *ctx, const struct hmac_md5_key *key);
/**
* hmac_md5_init_usingrawkey() - Initialize an HMAC-MD5 context for a new
* message, using a raw key
* @ctx: (output) the HMAC context to initialize
* @raw_key: the raw HMAC-MD5 key
* @raw_key_len: the key length in bytes. All key lengths are supported.
*
* If you don't need incremental computation, consider hmac_md5_usingrawkey()
* instead.
*
* Context: Any context.
*/
void hmac_md5_init_usingrawkey(struct hmac_md5_ctx *ctx,
const u8 *raw_key, size_t raw_key_len);
/**
* hmac_md5_update() - Update an HMAC-MD5 context with message data
* @ctx: the HMAC context to update; must have been initialized
* @data: the message data
* @data_len: the data length in bytes
*
* This can be called any number of times.
*
* Context: Any context.
*/
static inline void hmac_md5_update(struct hmac_md5_ctx *ctx,
const u8 *data, size_t data_len)
{
md5_update(&ctx->hash_ctx, data, data_len);
}
/**
* hmac_md5_final() - Finish computing an HMAC-MD5 value
* @ctx: the HMAC context to finalize; must have been initialized
* @out: (output) the resulting HMAC-MD5 value
*
* After finishing, this zeroizes @ctx. So the caller does not need to do it.
*
* Context: Any context.
*/
void hmac_md5_final(struct hmac_md5_ctx *ctx, u8 out[MD5_DIGEST_SIZE]);
/**
* hmac_md5() - Compute HMAC-MD5 in one shot, using a prepared key
* @key: the prepared HMAC key
* @data: the message data
* @data_len: the data length in bytes
* @out: (output) the resulting HMAC-MD5 value
*
* If you're using the key only once, consider using hmac_md5_usingrawkey().
*
* Context: Any context.
*/
void hmac_md5(const struct hmac_md5_key *key,
const u8 *data, size_t data_len, u8 out[MD5_DIGEST_SIZE]);
/**
* hmac_md5_usingrawkey() - Compute HMAC-MD5 in one shot, using a raw key
* @raw_key: the raw HMAC-MD5 key
* @raw_key_len: the key length in bytes. All key lengths are supported.
* @data: the message data
* @data_len: the data length in bytes
* @out: (output) the resulting HMAC-MD5 value
*
* If you're using the key multiple times, prefer to use hmac_md5_preparekey()
* followed by multiple calls to hmac_md5() instead.
*
* Context: Any context.
*/
void hmac_md5_usingrawkey(const u8 *raw_key, size_t raw_key_len,
const u8 *data, size_t data_len,
u8 out[MD5_DIGEST_SIZE]);
#endif /* _CRYPTO_MD5_H */
|