summaryrefslogtreecommitdiffstats
path: root/src/crypto/axtls_aes.c
blob: 278f933447c459e28142ef93064acc2357ad165d (plain) (blame)
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
#include "crypto/axtls/crypto.h"
#include <string.h>
#include <errno.h>
#include <gpxe/crypto.h>
#include <gpxe/aes.h>

struct aes_cbc_context {
	AES_CTX ctx;
	int decrypting;
};

static int aes_cbc_setkey ( void *ctx, const void *key, size_t keylen ) {
	struct aes_cbc_context *aesctx = ctx;
	AES_MODE mode;

	switch ( keylen ) {
	case ( 128 / 8 ):
		mode = AES_MODE_128;
		break;
	case ( 256 / 8 ):
		mode = AES_MODE_256;
		break;
	default:
		return -EINVAL;
	}

	AES_set_key ( &aesctx->ctx, key, aesctx->ctx.iv, mode );

	aesctx->decrypting = 0;

	return 0;
}

static void aes_cbc_setiv ( void *ctx, const void *iv ) {
	struct aes_cbc_context *aesctx = ctx;

	memcpy ( aesctx->ctx.iv, iv, sizeof ( aesctx->ctx.iv ) );
}

static void aes_cbc_encrypt ( void *ctx, const void *data, void *dst,
			      size_t len ) {
	struct aes_cbc_context *aesctx = ctx;

	if ( aesctx->decrypting )
		assert ( 0 );

	AES_cbc_encrypt ( &aesctx->ctx, data, dst, len );
}

static void aes_cbc_decrypt ( void *ctx, const void *data, void *dst,
			      size_t len ) {
	struct aes_cbc_context *aesctx = ctx;

	if ( ! aesctx->decrypting ) {
		AES_convert_key ( &aesctx->ctx );
		aesctx->decrypting = 1;
	}

	AES_cbc_decrypt ( &aesctx->ctx, data, dst, len );
}

struct crypto_algorithm aes_cbc_algorithm = {
	.name		= "aes_cbc",
	.ctxsize	= sizeof ( struct aes_cbc_context ),
	.blocksize	= 16,
	.setkey		= aes_cbc_setkey,
	.setiv		= aes_cbc_setiv,
	.encode		= aes_cbc_encrypt,
	.decode		= aes_cbc_decrypt,
};