File: encr_aes_cbc.c

package info (click to toggle)
rpc2 2.4%2Bdebian-1
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 2,832 kB
  • ctags: 2,657
  • sloc: ansic: 19,563; sh: 9,022; lex: 437; yacc: 416; makefile: 127; asm: 35; perl: 17
file content (110 lines) | stat: -rw-r--r-- 2,648 bytes parent folder | download | duplicates (2)
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
/* BLURB lgpl
			Coda File System
			    Release 6

	    Copyright (c) 2006 Carnegie Mellon University
		  Additional copyrights listed below

This  code  is  distributed "AS IS" without warranty of any kind under
the  terms of the  GNU  Library General Public Licence  Version 2,  as
shown in the file LICENSE. The technical and financial contributors to
Coda are listed in the file CREDITS.

			Additional copyrights
#*/

#include <string.h>
#include <stdlib.h>
#include <assert.h>

#include <rpc2/secure.h>
#include "aes.h"
#include "grunt.h"

static int encrypt_init(void **ctx, const uint8_t *key, size_t len)
{
    *ctx = malloc(sizeof(aes_encrypt_ctx));
    if (!*ctx) return 0;

    if      (len >= bytes(256)) len = 256;
    else if (len >= bytes(192)) len = 192;
    else if (len >= bytes(128)) len = 128;
    else goto err_out;

    if (aes_encrypt_key(key, len, *ctx) == 0)
	return 0;

err_out:
    free(*ctx);
    *ctx = NULL;
    return -1;
}

static int encrypt(void *ctx, const uint8_t *in, uint8_t *out, size_t len,
		   uint8_t *iv, const uint8_t *aad, size_t aad_len)
{
    /* CBC mode encryption requires an unpredictable IV, so we encrypt the
     * passed IV block (which is a counter) once. */
    aes_encrypt(iv, iv, ctx);

    return aes_cbc_encrypt(in, out, len, iv, ctx);
}

static void encrypt_free(void **ctx)
{
    if (!*ctx) return;
    memset(*ctx, 0, sizeof(aes_encrypt_ctx));
    free(*ctx);
    *ctx = NULL;
}


static int decrypt_init(void **ctx, const uint8_t *key, size_t len)
{
    *ctx = malloc(sizeof(aes_decrypt_ctx));
    if (!*ctx) return 0;

    if      (len >= bytes(256)) len = 256;
    else if (len >= bytes(192)) len = 192;
    else if (len >= bytes(128)) len = 128;
    else goto err_out;

    if (aes_decrypt_key(key, len, *ctx) == 0)
	return 0;

err_out:
    free(*ctx);
    *ctx = NULL;
    return -1;
}

static int decrypt(void *ctx, const uint8_t *in, uint8_t *out, size_t len,
		   const uint8_t *iv, const uint8_t *aad, size_t aad_len)
{
    return aes_cbc_decrypt(in, out, len, iv, ctx);
}

static void decrypt_free(void **ctx)
{
    if (!*ctx) return;
    memset(*ctx, 0, sizeof(aes_decrypt_ctx));
    free(*ctx);
    *ctx = NULL;
}


struct secure_encr secure_ENCR_AES_CBC = {
    .id	          = SECURE_ENCR_AES_CBC,
    .name         = "ENCR-AES-CBC",
    .encrypt_init = encrypt_init,
    .encrypt_free = encrypt_free,
    .encrypt      = encrypt,
    .decrypt_init = decrypt_init,
    .decrypt_free = decrypt_free,
    .decrypt      = decrypt,
    .min_keysize  = bytes(128),
    .max_keysize  = bytes(256),
    .blocksize    = AES_BLOCK_SIZE,
    .iv_len       = AES_BLOCK_SIZE,
};