1/* SPDX-License-Identifier: GPL-2.0+ */
2/*
3 * Copyright (c) 2012 The Chromium OS Authors.
4 */
5
6#ifndef _HASH_H
7#define _HASH_H
8
9#ifdef USE_HOSTCC
10#include <linux/kconfig.h>
11#endif
12
13struct cmd_tbl;
14
15/*
16 * Maximum digest size for all algorithms we support. Having this value
17 * avoids a malloc() or C99 local declaration in common/cmd_hash.c.
18 */
19#if CONFIG_IS_ENABLED(SHA384) || CONFIG_IS_ENABLED(SHA512)
20#define HASH_MAX_DIGEST_SIZE	64
21#else
22#define HASH_MAX_DIGEST_SIZE	32
23#endif
24
25enum {
26	HASH_FLAG_VERIFY	= 1 << 0,	/* Enable verify mode */
27	HASH_FLAG_ENV		= 1 << 1,	/* Allow env vars */
28};
29
30struct hash_algo {
31	const char *name;			/* Name of algorithm */
32	int digest_size;			/* Length of digest */
33	/**
34	 * hash_func_ws: Generic hashing function
35	 *
36	 * This is the generic prototype for a hashing function. We only
37	 * have the watchdog version at present.
38	 *
39	 * @input:	Input buffer
40	 * @ilen:	Input buffer length
41	 * @output:	Checksum result (length depends on algorithm)
42	 * @chunk_sz:	Trigger watchdog after processing this many bytes
43	 */
44	void (*hash_func_ws)(const unsigned char *input, unsigned int ilen,
45		unsigned char *output, unsigned int chunk_sz);
46	int chunk_size;				/* Watchdog chunk size */
47	/*
48	 * hash_init: Create the context for progressive hashing
49	 *
50	 * @algo: Pointer to the hash_algo struct
51	 * @ctxp: Pointer to the pointer of the context for hashing
52	 * @return 0 if ok, -1 on error
53	 */
54	int (*hash_init)(struct hash_algo *algo, void **ctxp);
55	/*
56	 * hash_update: Perform hashing on the given buffer
57	 *
58	 * The context is freed by this function if an error occurs.
59	 *
60	 * @algo: Pointer to the hash_algo struct
61	 * @ctx: Pointer to the context for hashing
62	 * @buf: Pointer to the buffer being hashed
63	 * @size: Size of the buffer being hashed
64	 * @is_last: 1 if this is the last update; 0 otherwise
65	 * @return 0 if ok, -1 on error
66	 */
67	int (*hash_update)(struct hash_algo *algo, void *ctx, const void *buf,
68			   unsigned int size, int is_last);
69	/*
70	 * hash_finish: Write the hash result to the given buffer
71	 *
72	 * The context is freed by this function.
73	 *
74	 * @algo: Pointer to the hash_algo struct
75	 * @ctx: Pointer to the context for hashing
76	 * @dest_buf: Pointer to the buffer for the result
77	 * @size: Size of the buffer for the result
78	 * @return 0 if ok, -ENOSPC if size of the result buffer is too small
79	 *   or -1 on other errors
80	 */
81	int (*hash_finish)(struct hash_algo *algo, void *ctx, void *dest_buf,
82			   int size);
83};
84
85#ifndef USE_HOSTCC
86/**
87 * hash_command: Process a hash command for a particular algorithm
88 *
89 * This common function is used to implement specific hash commands.
90 *
91 * @algo_name:		Hash algorithm being used (lower case!)
92 * @flags:		Flags value (HASH_FLAG_...)
93 * @cmdtp:		Pointer to command table entry
94 * @flag:		Some flags normally 0 (see CMD_FLAG_.. above)
95 * @argc:		Number of arguments (arg 0 must be the command text)
96 * @argv:		Arguments
97 */
98int hash_command(const char *algo_name, int flags, struct cmd_tbl *cmdtp,
99		 int flag, int argc, char *const argv[]);
100
101/**
102 * hash_block() - Hash a block according to the requested algorithm
103 *
104 * The caller probably knows the hash length for the chosen algorithm, but
105 * in order to provide a general interface, and output_size parameter is
106 * provided.
107 *
108 * @algo_name:		Hash algorithm to use
109 * @data:		Data to hash
110 * @len:		Lengh of data to hash in bytes
111 * @output:		Place to put hash value
112 * @output_size:	On entry, pointer to the number of bytes available in
113 *			output. On exit, pointer to the number of bytes used.
114 *			If NULL, then it is assumed that the caller has
115 *			allocated enough space for the hash. This is possible
116 *			since the caller is selecting the algorithm.
117 * Return: 0 if ok, -ve on error: -EPROTONOSUPPORT for an unknown algorithm,
118 * -ENOSPC if the output buffer is not large enough.
119 */
120int hash_block(const char *algo_name, const void *data, unsigned int len,
121	       uint8_t *output, int *output_size);
122
123#endif /* !USE_HOSTCC */
124
125/**
126 * hash_lookup_algo() - Look up the hash_algo struct for an algorithm
127 *
128 * The function returns the pointer to the struct or -EPROTONOSUPPORT if the
129 * algorithm is not available.
130 *
131 * @algo_name: Hash algorithm to look up
132 * @algop: Pointer to the hash_algo struct if found
133 *
134 * Return: 0 if ok, -EPROTONOSUPPORT for an unknown algorithm.
135 */
136int hash_lookup_algo(const char *algo_name, struct hash_algo **algop);
137
138/**
139 * hash_progressive_lookup_algo() - Look up hash_algo for prog. hash support
140 *
141 * The function returns the pointer to the struct or -EPROTONOSUPPORT if the
142 * algorithm is not available with progressive hash support.
143 *
144 * @algo_name: Hash algorithm to look up
145 * @algop: Pointer to the hash_algo struct if found
146 *
147 * Return: 0 if ok, -EPROTONOSUPPORT for an unknown algorithm.
148 */
149int hash_progressive_lookup_algo(const char *algo_name,
150				 struct hash_algo **algop);
151
152/**
153 * hash_parse_string() - Parse hash string into a binary array
154 *
155 * The function parses a hash string into a binary array that
156 * can for example easily be used to compare to hash values.
157 *
158 * @algo_name: Hash algorithm to look up
159 * @str: Hash string to get parsed
160 * @result: Binary array of the parsed hash string
161 *
162 * Return: 0 if ok, -EPROTONOSUPPORT for an unknown algorithm.
163 */
164int hash_parse_string(const char *algo_name, const char *str, uint8_t *result);
165
166#endif
167