1#ifndef _GPXE_CRYPTO_H
2#define _GPXE_CRYPTO_H
3
4/** @file
5 *
6 * Cryptographic API
7 *
8 */
9
10FILE_LICENCE ( GPL2_OR_LATER );
11
12#include <stdint.h>
13#include <stddef.h>
14
15/** A message digest algorithm */
16struct digest_algorithm {
17	/** Algorithm name */
18	const char *name;
19	/** Context size */
20	size_t ctxsize;
21	/** Block size */
22	size_t blocksize;
23	/** Digest size */
24	size_t digestsize;
25	/** Initialise digest
26	 *
27	 * @v ctx		Context
28	 */
29	void ( * init ) ( void *ctx );
30	/** Update digest with new data
31	 *
32	 * @v ctx		Context
33	 * @v src		Data to digest
34	 * @v len		Length of data
35	 *
36	 * @v len is not necessarily a multiple of @c blocksize.
37	 */
38	void ( * update ) ( void *ctx, const void *src, size_t len );
39	/** Finalise digest
40	 *
41	 * @v ctx		Context
42	 * @v out		Buffer for digest output
43	 */
44	void ( * final ) ( void *ctx, void *out );
45};
46
47/** A cipher algorithm */
48struct cipher_algorithm {
49	/** Algorithm name */
50	const char *name;
51	/** Context size */
52	size_t ctxsize;
53	/** Block size */
54	size_t blocksize;
55	/** Set key
56	 *
57	 * @v ctx		Context
58	 * @v key		Key
59	 * @v keylen		Key length
60	 * @ret rc		Return status code
61	 */
62	int ( * setkey ) ( void *ctx, const void *key, size_t keylen );
63	/** Set initialisation vector
64	 *
65	 * @v ctx		Context
66	 * @v iv		Initialisation vector
67	 */
68	void ( * setiv ) ( void *ctx, const void *iv );
69	/** Encrypt data
70	 *
71	 * @v ctx		Context
72	 * @v src		Data to encrypt
73	 * @v dst		Buffer for encrypted data
74	 * @v len		Length of data
75	 *
76	 * @v len is guaranteed to be a multiple of @c blocksize.
77	 */
78	void ( * encrypt ) ( void *ctx, const void *src, void *dst,
79			     size_t len );
80	/** Decrypt data
81	 *
82	 * @v ctx		Context
83	 * @v src		Data to decrypt
84	 * @v dst		Buffer for decrypted data
85	 * @v len		Length of data
86	 *
87	 * @v len is guaranteed to be a multiple of @c blocksize.
88	 */
89	void ( * decrypt ) ( void *ctx, const void *src, void *dst,
90			     size_t len );
91};
92
93/** A public key algorithm */
94struct pubkey_algorithm {
95	/** Algorithm name */
96	const char *name;
97	/** Context size */
98	size_t ctxsize;
99};
100
101static inline void digest_init ( struct digest_algorithm *digest,
102				 void *ctx ) {
103	digest->init ( ctx );
104}
105
106static inline void digest_update ( struct digest_algorithm *digest,
107				   void *ctx, const void *data, size_t len ) {
108	digest->update ( ctx, data, len );
109}
110
111static inline void digest_final ( struct digest_algorithm *digest,
112				  void *ctx, void *out ) {
113	digest->final ( ctx, out );
114}
115
116static inline int cipher_setkey ( struct cipher_algorithm *cipher,
117				  void *ctx, const void *key, size_t keylen ) {
118	return cipher->setkey ( ctx, key, keylen );
119}
120
121static inline void cipher_setiv ( struct cipher_algorithm *cipher,
122				  void *ctx, const void *iv ) {
123	cipher->setiv ( ctx, iv );
124}
125
126static inline void cipher_encrypt ( struct cipher_algorithm *cipher,
127				    void *ctx, const void *src, void *dst,
128				    size_t len ) {
129	cipher->encrypt ( ctx, src, dst, len );
130}
131#define cipher_encrypt( cipher, ctx, src, dst, len ) do {		\
132	assert ( ( (len) & ( (cipher)->blocksize - 1 ) ) == 0 );	\
133	cipher_encrypt ( (cipher), (ctx), (src), (dst), (len) );	\
134	} while ( 0 )
135
136static inline void cipher_decrypt ( struct cipher_algorithm *cipher,
137				    void *ctx, const void *src, void *dst,
138				    size_t len ) {
139	cipher->decrypt ( ctx, src, dst, len );
140}
141#define cipher_decrypt( cipher, ctx, src, dst, len ) do {		\
142	assert ( ( (len) & ( (cipher)->blocksize - 1 ) ) == 0 );	\
143	cipher_decrypt ( (cipher), (ctx), (src), (dst), (len) );	\
144	} while ( 0 )
145
146static inline int is_stream_cipher ( struct cipher_algorithm *cipher ) {
147	return ( cipher->blocksize == 1 );
148}
149
150extern struct digest_algorithm digest_null;
151extern struct cipher_algorithm cipher_null;
152extern struct pubkey_algorithm pubkey_null;
153
154void get_random_bytes ( void *buf, size_t len );
155
156#endif /* _GPXE_CRYPTO_H */
157