summaryrefslogtreecommitdiff
path: root/gpxe/src/include/gpxe/crypto.h
blob: 95665acc51d6e98be0bb8e0c798f637c60bb50c2 (plain)
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
#ifndef _GPXE_CRYPTO_H
#define _GPXE_CRYPTO_H

/** @file
 *
 * Cryptographic API
 *
 */

#include <stdint.h>
#include <stddef.h>

/** A cryptographic algorithm */
struct crypto_algorithm {
	/** Algorithm name */
	const char *name;
	/** Context size */
	size_t ctxsize;
	/** Block size */
	size_t blocksize;
	/** Final output size */
	size_t digestsize;
	/** Initialise algorithm
	 *
	 * @v ctx		Context
	 */
	void ( * init ) ( void *ctx );
	/** Set key
	 *
	 * @v ctx		Context
	 * @v key		Key
	 * @v keylen		Key length
	 * @ret rc		Return status code
	 */
	int ( * setkey ) ( void *ctx, const void *key, size_t keylen );
	/** Set initialisation vector
	 *
	 * @v ctx		Context
	 * @v iv		Initialisation vector
	 */
	void ( *setiv ) ( void *ctx, const void *iv );
	/** Encode data
	 *
	 * @v ctx		Context
	 * @v src		Data to encode
	 * @v dst		Encoded data, or NULL
	 * @v len		Length of data
	 * @ret rc		Return status code
	 *
	 * For a cipher algorithm, the enciphered data should be
	 * placed in @c dst.  For a digest algorithm, only the digest
	 * state should be updated, and @c dst will be NULL.
	 *
	 * @v len is guaranteed to be a multiple of @c blocksize.
	 */
	void ( * encode ) ( void *ctx, const void *src, void *dst,
			    size_t len );
	/** Decode data
	 *
	 * @v ctx		Context
	 * @v src		Data to decode
	 * @v dst		Decoded data
	 * @v len		Length of data
	 * @ret rc		Return status code
	 *
	 * @v len is guaranteed to be a multiple of @c blocksize.
	 */
	void ( * decode ) ( void *ctx, const void *src, void *dst,
			    size_t len );
	/** Finalise algorithm
	 *
	 * @v ctx		Context
	 * @v out		Algorithm final output
	 */
	void ( * final ) ( void *ctx, void *out );
};

static inline void digest_init ( struct crypto_algorithm *crypto,
				 void *ctx ) {
	crypto->init ( ctx );
}

static inline void digest_update ( struct crypto_algorithm *crypto,
				   void *ctx, const void *data, size_t len ) {
	crypto->encode ( ctx, data, NULL, len );
}

static inline void digest_final ( struct crypto_algorithm *crypto,
				  void *ctx, void *out ) {
	crypto->final ( ctx, out );
}

static inline void cipher_setiv ( struct crypto_algorithm *crypto,
				  void *ctx, const void *iv ) {
	crypto->setiv ( ctx, iv );
}

static inline int cipher_setkey ( struct crypto_algorithm *crypto,
				  void *ctx, const void *key, size_t keylen ) {
	return crypto->setkey ( ctx, key, keylen );
}

static inline int is_stream_cipher ( struct crypto_algorithm *crypto ) {
	return ( crypto->blocksize == 1 );
}

extern struct crypto_algorithm crypto_null;

extern int cipher_encrypt ( struct crypto_algorithm *crypto,
			    void *ctx, const void *src, void *dst,
			    size_t len );
extern int cipher_decrypt ( struct crypto_algorithm *crypto,
			    void *ctx, const void *src, void *dst,
			    size_t len );

#endif /* _GPXE_CRYPTO_H */