Преглед изворни кода

[crypto] Allow creation of arbitrary CBC cipher algorithms using CBC_CIPHER()

Given any block cipher, a corresponding CBC mode of behaviour for the
cipher can be created using the CBC_CIPHER() macro.
tags/v0.9.7
Michael Brown пре 15 година
родитељ
комит
9937bf13c9
3 измењених фајлова са 66 додато и 106 уклоњено
  1. 2
    90
      src/crypto/axtls_aes.c
  2. 8
    8
      src/crypto/cbc.c
  3. 56
    8
      src/include/gpxe/cbc.h

+ 2
- 90
src/crypto/axtls_aes.c Прегледај датотеку

@@ -33,13 +33,6 @@
33 33
 /** Basic AES blocksize */
34 34
 #define AES_BLOCKSIZE 16
35 35
 
36
-/****************************************************************************
37
- *
38
- * Basic AES algorithm (independent of mode of operation)
39
- *
40
- ****************************************************************************
41
- */
42
-
43 36
 /** AES context */
44 37
 struct aes_context {
45 38
 	/** AES context for AXTLS */
@@ -169,87 +162,6 @@ static struct cipher_algorithm aes_algorithm = {
169 162
 	.decrypt = aes_decrypt,
170 163
 };
171 164
 
172
-/****************************************************************************
173
- *
174
- * AES with cipher-block chaining (CBC)
175
- *
176
- ****************************************************************************
177
- */
178
-
179
-/** AES with CBC context */
180
-struct aes_cbc_context {
181
-	/** AES context */
182
-	struct aes_context aes_ctx;
183
-	/** CBC context */
184
-	uint8_t cbc_ctx[AES_BLOCKSIZE];
185
-};
186
-
187
-/**
188
- * Set key
189
- *
190
- * @v ctx		Context
191
- * @v key		Key
192
- * @v keylen		Key length
193
- * @ret rc		Return status code
194
- */
195
-static int aes_cbc_setkey ( void *ctx, const void *key, size_t keylen ) {
196
-	struct aes_cbc_context *aes_cbc_ctx = ctx;
197
-
198
-	return cbc_setkey ( ctx, key, keylen, &aes_algorithm,
199
-			    &aes_cbc_ctx->cbc_ctx );
200
-}
201
-
202
-/**
203
- * Set initialisation vector
204
- *
205
- * @v ctx		Context
206
- * @v iv		Initialisation vector
207
- */
208
-static void aes_cbc_setiv ( void *ctx, const void *iv ) {
209
-	struct aes_cbc_context *aes_cbc_ctx = ctx;
210
-
211
-	cbc_setiv ( ctx, iv, &aes_algorithm, &aes_cbc_ctx->cbc_ctx );
212
-}
213
-
214
-/**
215
- * Encrypt data
216
- *
217
- * @v ctx		Context
218
- * @v src		Data to encrypt
219
- * @v dst		Buffer for encrypted data
220
- * @v len		Length of data
221
- */
222
-static void aes_cbc_encrypt ( void *ctx, const void *src, void *dst,
223
-			      size_t len ) {
224
-	struct aes_cbc_context *aes_cbc_ctx = ctx;
225
-
226
-	cbc_encrypt ( &aes_cbc_ctx->aes_ctx, src, dst, len,
227
-		      &aes_algorithm, &aes_cbc_ctx->cbc_ctx );
228
-}
229
-
230
-/**
231
- * Decrypt data
232
- *
233
- * @v ctx		Context
234
- * @v src		Data to decrypt
235
- * @v dst		Buffer for decrypted data
236
- * @v len		Length of data
237
- */
238
-static void aes_cbc_decrypt ( void *ctx, const void *src, void *dst,
239
-			      size_t len ) {
240
-	struct aes_cbc_context *aes_cbc_ctx = ctx;
241
-
242
-	cbc_decrypt ( &aes_cbc_ctx->aes_ctx, src, dst, len,
243
-		      &aes_algorithm, &aes_cbc_ctx->cbc_ctx );
244
-}
245
-
246 165
 /* AES with cipher-block chaining */
247
-struct cipher_algorithm aes_cbc_algorithm = {
248
-	.name		= "aes_cbc",
249
-	.ctxsize	= sizeof ( struct aes_cbc_context ),
250
-	.blocksize	= AES_BLOCKSIZE,
251
-	.setkey		= aes_cbc_setkey,
252
-	.setiv		= aes_cbc_setiv,
253
-	.encrypt	= aes_cbc_encrypt,
254
-	.decrypt	= aes_cbc_decrypt,
255
-};
166
+CBC_CIPHER ( aes_cbc, aes_cbc_algorithm,
167
+	     aes_algorithm, struct aes_context, AES_BLOCKSIZE );

+ 8
- 8
src/crypto/cbc.c Прегледај датотеку

@@ -53,18 +53,18 @@ static void cbc_xor ( const void *src, void *dst, size_t len ) {
53 53
  * @v src		Data to encrypt
54 54
  * @v dst		Buffer for encrypted data
55 55
  * @v len		Length of data
56
- * @v cipher		Underlying cipher algorithm
56
+ * @v raw_cipher	Underlying cipher algorithm
57 57
  * @v cbc_ctx		CBC context
58 58
  */
59 59
 void cbc_encrypt ( void *ctx, const void *src, void *dst, size_t len,
60
-		   struct cipher_algorithm *cipher, void *cbc_ctx ) {
61
-	size_t blocksize = cipher->blocksize;
60
+		   struct cipher_algorithm *raw_cipher, void *cbc_ctx ) {
61
+	size_t blocksize = raw_cipher->blocksize;
62 62
 
63 63
 	assert ( ( len % blocksize ) == 0 );
64 64
 
65 65
 	while ( len ) {
66 66
 		cbc_xor ( src, cbc_ctx, blocksize );
67
-		cipher_encrypt ( cipher, ctx, cbc_ctx, dst, blocksize );
67
+		cipher_encrypt ( raw_cipher, ctx, cbc_ctx, dst, blocksize );
68 68
 		memcpy ( cbc_ctx, dst, blocksize );
69 69
 		dst += blocksize;
70 70
 		src += blocksize;
@@ -79,17 +79,17 @@ void cbc_encrypt ( void *ctx, const void *src, void *dst, size_t len,
79 79
  * @v src		Data to decrypt
80 80
  * @v dst		Buffer for decrypted data
81 81
  * @v len		Length of data
82
- * @v cipher		Underlying cipher algorithm
82
+ * @v raw_cipher	Underlying cipher algorithm
83 83
  * @v cbc_ctx		CBC context
84 84
  */
85 85
 void cbc_decrypt ( void *ctx, const void *src, void *dst, size_t len,
86
-		   struct cipher_algorithm *cipher, void *cbc_ctx ) {
87
-	size_t blocksize = cipher->blocksize;
86
+		   struct cipher_algorithm *raw_cipher, void *cbc_ctx ) {
87
+	size_t blocksize = raw_cipher->blocksize;
88 88
 
89 89
 	assert ( ( len % blocksize ) == 0 );
90 90
 
91 91
 	while ( len ) {
92
-		cipher_decrypt ( cipher, ctx, src, dst, blocksize );
92
+		cipher_decrypt ( raw_cipher, ctx, src, dst, blocksize );
93 93
 		cbc_xor ( cbc_ctx, dst, blocksize );
94 94
 		memcpy ( cbc_ctx, src, blocksize );
95 95
 		dst += blocksize;

+ 56
- 8
src/include/gpxe/cbc.h Прегледај датотеку

@@ -15,15 +15,15 @@
15 15
  * @v ctx		Context
16 16
  * @v key		Key
17 17
  * @v keylen		Key length
18
- * @v cipher		Underlying cipher algorithm
18
+ * @v raw_cipher	Underlying cipher algorithm
19 19
  * @v cbc_ctx		CBC context
20 20
  * @ret rc		Return status code
21 21
  */
22 22
 static inline int cbc_setkey ( void *ctx, const void *key, size_t keylen,
23
-			       struct cipher_algorithm *cipher,
23
+			       struct cipher_algorithm *raw_cipher,
24 24
 			       void *cbc_ctx __unused ) {
25 25
 
26
-	return cipher_setkey ( cipher, ctx, key, keylen );
26
+	return cipher_setkey ( raw_cipher, ctx, key, keylen );
27 27
 }
28 28
 
29 29
 /**
@@ -31,20 +31,68 @@ static inline int cbc_setkey ( void *ctx, const void *key, size_t keylen,
31 31
  *
32 32
  * @v ctx		Context
33 33
  * @v iv		Initialisation vector
34
- * @v cipher		Underlying cipher algorithm
34
+ * @v raw_cipher	Underlying cipher algorithm
35 35
  * @v cbc_ctx		CBC context
36 36
  */
37 37
 static inline void cbc_setiv ( void *ctx __unused, const void *iv,
38
-			       struct cipher_algorithm *cipher,
38
+			       struct cipher_algorithm *raw_cipher,
39 39
 			       void *cbc_ctx ) {
40
-	memcpy ( cbc_ctx, iv, cipher->blocksize );
40
+	memcpy ( cbc_ctx, iv, raw_cipher->blocksize );
41 41
 }
42 42
 
43 43
 extern void cbc_encrypt ( void *ctx, const void *src, void *dst,
44
-			  size_t len, struct cipher_algorithm *cipher,
44
+			  size_t len, struct cipher_algorithm *raw_cipher,
45 45
 			  void *cbc_ctx );
46 46
 extern void cbc_decrypt ( void *ctx, const void *src, void *dst,
47
-			  size_t len, struct cipher_algorithm *cipher,
47
+			  size_t len, struct cipher_algorithm *raw_cipher,
48 48
 			  void *cbc_ctx );
49 49
 
50
+/**
51
+ * Create a cipher-block chaining mode of behaviour of an existing cipher
52
+ *
53
+ * @v _cbc_name		Name for the new CBC cipher
54
+ * @v _cbc_cipher	New cipher algorithm
55
+ * @v _raw_cipher	Underlying cipher algorithm
56
+ * @v _raw_context	Context structure for the underlying cipher
57
+ * @v _blocksize	Cipher block size
58
+ */
59
+#define CBC_CIPHER( _cbc_name, _cbc_cipher, _raw_cipher, _raw_context,	\
60
+		    _blocksize )					\
61
+struct _cbc_name ## _context {						\
62
+	_raw_context raw_ctx;						\
63
+	uint8_t cbc_ctx[_blocksize];					\
64
+};									\
65
+static int _cbc_name ## _setkey ( void *ctx, const void *key,		\
66
+				  size_t keylen ) {			\
67
+	struct _cbc_name ## _context * _cbc_name ## _ctx = ctx;		\
68
+	return cbc_setkey ( &_cbc_name ## _ctx->raw_ctx, key, keylen,	\
69
+			    &_raw_cipher, &_cbc_name ## _ctx->cbc_ctx );\
70
+}									\
71
+static void _cbc_name ## _setiv ( void *ctx, const void *iv ) {		\
72
+	struct _cbc_name ## _context * _cbc_name ## _ctx = ctx;		\
73
+	cbc_setiv ( &_cbc_name ## _ctx->raw_ctx, iv,			\
74
+		    &_raw_cipher, &aes_cbc_ctx->cbc_ctx );		\
75
+}									\
76
+static void _cbc_name ## _encrypt ( void *ctx, const void *src,		\
77
+				    void *dst, size_t len ) {		\
78
+	struct _cbc_name ## _context * _cbc_name ## _ctx = ctx;		\
79
+	cbc_encrypt ( &_cbc_name ## _ctx->raw_ctx, src, dst, len,	\
80
+		      &_raw_cipher, &aes_cbc_ctx->cbc_ctx );		\
81
+}									\
82
+static void _cbc_name ## _decrypt ( void *ctx, const void *src,		\
83
+				    void *dst, size_t len ) {		\
84
+	struct _cbc_name ## _context * _cbc_name ## _ctx = ctx;		\
85
+	cbc_decrypt ( &_cbc_name ## _ctx->raw_ctx, src, dst, len,	\
86
+		      &_raw_cipher, &aes_cbc_ctx->cbc_ctx );		\
87
+}									\
88
+struct cipher_algorithm _cbc_cipher = {					\
89
+	.name		= #_cbc_name,					\
90
+	.ctxsize	= sizeof ( struct _cbc_name ## _context ),	\
91
+	.blocksize	= _blocksize,					\
92
+	.setkey		= _cbc_name ## _setkey,				\
93
+	.setiv		= _cbc_name ## _setiv,				\
94
+	.encrypt	= _cbc_name ## _encrypt,			\
95
+	.decrypt	= _cbc_name ## _decrypt,			\
96
+};
97
+
50 98
 #endif /* _GPXE_CBC_H */

Loading…
Откажи
Сачувај