Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/stand/libsa/geli/geliboot_crypto.c
34860 views
1
/*-
2
* Copyright (c) 2005-2010 Pawel Jakub Dawidek <[email protected]>
3
* Copyright (c) 2015 Allan Jude <[email protected]>
4
* All rights reserved.
5
*
6
* Redistribution and use in source and binary forms, with or without
7
* modification, are permitted provided that the following conditions
8
* are met:
9
* 1. Redistributions of source code must retain the above copyright
10
* notice, this list of conditions and the following disclaimer.
11
* 2. Redistributions in binary form must reproduce the above copyright
12
* notice, this list of conditions and the following disclaimer in the
13
* documentation and/or other materials provided with the distribution.
14
*
15
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
16
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
19
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25
* SUCH DAMAGE.
26
*/
27
28
#include <stdio.h>
29
#include <string.h>
30
#include <strings.h>
31
32
#include "geliboot_internal.h"
33
#include "geliboot.h"
34
35
int
36
geliboot_crypt(u_int algo, geli_op_t enc, u_char *data, size_t datasize,
37
const u_char *key, size_t keysize, u_char *iv)
38
{
39
keyInstance aeskey;
40
cipherInstance cipher;
41
struct aes_xts_ctx xtsctx, *ctxp;
42
size_t xts_len;
43
int err, blks;
44
45
switch (algo) {
46
case CRYPTO_AES_CBC:
47
err = rijndael_makeKey(&aeskey, !enc, keysize,
48
(const char *)key);
49
if (err < 0) {
50
printf("Failed to setup crypo keys: %d\n", err);
51
return (err);
52
}
53
54
err = rijndael_cipherInit(&cipher, MODE_CBC, iv);
55
if (err < 0) {
56
printf("Failed to setup IV: %d\n", err);
57
return (err);
58
}
59
60
switch (enc) {
61
case GELI_DECRYPT:
62
blks = rijndael_blockDecrypt(&cipher, &aeskey, data,
63
datasize * 8, data);
64
break;
65
case GELI_ENCRYPT:
66
blks = rijndael_blockEncrypt(&cipher, &aeskey, data,
67
datasize * 8, data);
68
break;
69
}
70
if (datasize != (blks / 8)) {
71
printf("Failed to %s the entire input: %u != %zu\n",
72
enc ? "decrypt" : "encrypt",
73
blks, datasize);
74
return (1);
75
}
76
break;
77
case CRYPTO_AES_XTS:
78
xts_len = keysize << 1;
79
ctxp = &xtsctx;
80
81
enc_xform_aes_xts.setkey(ctxp, key, xts_len / 8);
82
enc_xform_aes_xts.reinit(ctxp, iv, AES_XTS_IV_LEN);
83
84
switch (enc) {
85
case GELI_DECRYPT:
86
enc_xform_aes_xts.decrypt_multi(ctxp, data, data,
87
datasize);
88
break;
89
case GELI_ENCRYPT:
90
enc_xform_aes_xts.encrypt_multi(ctxp, data, data,
91
datasize);
92
break;
93
}
94
break;
95
default:
96
printf("Unsupported crypto algorithm #%d\n", algo);
97
return (1);
98
}
99
100
return (0);
101
}
102
103
static int
104
g_eli_crypto_cipher(u_int algo, geli_op_t enc, u_char *data, size_t datasize,
105
const u_char *key, size_t keysize)
106
{
107
u_char iv[G_ELI_IVKEYLEN];
108
109
explicit_bzero(iv, sizeof(iv));
110
return (geliboot_crypt(algo, enc, data, datasize, key, keysize, iv));
111
}
112
113
int
114
g_eli_crypto_encrypt(u_int algo, u_char *data, size_t datasize,
115
const u_char *key, size_t keysize)
116
{
117
118
/* We prefer AES-CBC for metadata protection. */
119
if (algo == CRYPTO_AES_XTS)
120
algo = CRYPTO_AES_CBC;
121
122
return (g_eli_crypto_cipher(algo, GELI_ENCRYPT, data, datasize, key,
123
keysize));
124
}
125
126
int
127
g_eli_crypto_decrypt(u_int algo, u_char *data, size_t datasize,
128
const u_char *key, size_t keysize)
129
{
130
131
/* We prefer AES-CBC for metadata protection. */
132
if (algo == CRYPTO_AES_XTS)
133
algo = CRYPTO_AES_CBC;
134
135
return (g_eli_crypto_cipher(algo, GELI_DECRYPT, data, datasize, key,
136
keysize));
137
}
138
139