"Fossies" - the Fresh Open Source Software Archive 
Member "cryptsetup-2.4.3/lib/luks1/keyencryption.c" (13 Jan 2022, 7817 Bytes) of package /linux/misc/cryptsetup-2.4.3.tar.xz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "keyencryption.c" see the
Fossies "Dox" file reference documentation.
1 /*
2 * LUKS - Linux Unified Key Setup
3 *
4 * Copyright (C) 2004-2006 Clemens Fruhwirth <clemens@endorphin.org>
5 * Copyright (C) 2009-2021 Red Hat, Inc. All rights reserved.
6 * Copyright (C) 2012-2021 Milan Broz
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 */
22
23 #include <stdio.h>
24 #include <string.h>
25 #include <errno.h>
26 #include <sys/stat.h>
27 #include "luks.h"
28 #include "af.h"
29 #include "internal.h"
30
31 static void _error_hint(struct crypt_device *ctx, const char *device,
32 const char *cipher, const char *mode, size_t keyLength)
33 {
34 char *c, cipher_spec[MAX_CIPHER_LEN * 3];
35
36 if (snprintf(cipher_spec, sizeof(cipher_spec), "%s-%s", cipher, mode) < 0)
37 return;
38
39 log_err(ctx, _("Failed to setup dm-crypt key mapping for device %s.\n"
40 "Check that kernel supports %s cipher (check syslog for more info)."),
41 device, cipher_spec);
42
43 if (!strncmp(mode, "xts", 3) && (keyLength != 256 && keyLength != 512))
44 log_err(ctx, _("Key size in XTS mode must be 256 or 512 bits."));
45 else if (!(c = strchr(mode, '-')) || strlen(c) < 4)
46 log_err(ctx, _("Cipher specification should be in [cipher]-[mode]-[iv] format."));
47 }
48
49 static int LUKS_endec_template(char *src, size_t srcLength,
50 const char *cipher, const char *cipher_mode,
51 struct volume_key *vk,
52 unsigned int sector,
53 ssize_t (*func)(int, size_t, size_t, void *, size_t),
54 int mode,
55 struct crypt_device *ctx)
56 {
57 char name[PATH_MAX], path[PATH_MAX];
58 char cipher_spec[MAX_CIPHER_LEN * 3];
59 struct crypt_dm_active_device dmd = {
60 .flags = CRYPT_ACTIVATE_PRIVATE,
61 };
62 int r, devfd = -1, remove_dev = 0;
63 size_t bsize, keyslot_alignment, alignment;
64
65 log_dbg(ctx, "Using dmcrypt to access keyslot area.");
66
67 bsize = device_block_size(ctx, crypt_metadata_device(ctx));
68 alignment = device_alignment(crypt_metadata_device(ctx));
69 if (!bsize || !alignment)
70 return -EINVAL;
71
72 if (bsize > LUKS_ALIGN_KEYSLOTS)
73 keyslot_alignment = LUKS_ALIGN_KEYSLOTS;
74 else
75 keyslot_alignment = bsize;
76 dmd.size = size_round_up(srcLength, keyslot_alignment) / SECTOR_SIZE;
77
78 if (mode == O_RDONLY)
79 dmd.flags |= CRYPT_ACTIVATE_READONLY;
80
81 if (snprintf(name, sizeof(name), "temporary-cryptsetup-%d", getpid()) < 0)
82 return -ENOMEM;
83 if (snprintf(path, sizeof(path), "%s/%s", dm_get_dir(), name) < 0)
84 return -ENOMEM;
85 if (snprintf(cipher_spec, sizeof(cipher_spec), "%s-%s", cipher, cipher_mode) < 0)
86 return -ENOMEM;
87
88 r = device_block_adjust(ctx, crypt_metadata_device(ctx), DEV_OK,
89 sector, &dmd.size, &dmd.flags);
90 if (r < 0) {
91 log_err(ctx, _("Device %s does not exist or access denied."),
92 device_path(crypt_metadata_device(ctx)));
93 return -EIO;
94 }
95
96 if (mode != O_RDONLY && dmd.flags & CRYPT_ACTIVATE_READONLY) {
97 log_err(ctx, _("Cannot write to device %s, permission denied."),
98 device_path(crypt_metadata_device(ctx)));
99 return -EACCES;
100 }
101
102 r = dm_crypt_target_set(&dmd.segment, 0, dmd.size,
103 crypt_metadata_device(ctx), vk, cipher_spec, 0, sector,
104 NULL, 0, SECTOR_SIZE);
105 if (r)
106 goto out;
107
108 r = dm_create_device(ctx, name, "TEMP", &dmd);
109 if (r < 0) {
110 if (r != -EACCES && r != -ENOTSUP)
111 _error_hint(ctx, device_path(crypt_metadata_device(ctx)),
112 cipher, cipher_mode, vk->keylength * 8);
113 r = -EIO;
114 goto out;
115 }
116 remove_dev = 1;
117
118 devfd = open(path, mode | O_DIRECT | O_SYNC);
119 if (devfd == -1) {
120 log_err(ctx, _("Failed to open temporary keystore device."));
121 r = -EIO;
122 goto out;
123 }
124
125 r = func(devfd, bsize, alignment, src, srcLength);
126 if (r < 0) {
127 log_err(ctx, _("Failed to access temporary keystore device."));
128 r = -EIO;
129 } else
130 r = 0;
131 out:
132 dm_targets_free(ctx, &dmd);
133 if (devfd != -1)
134 close(devfd);
135 if (remove_dev)
136 dm_remove_device(ctx, name, CRYPT_DEACTIVATE_FORCE);
137 return r;
138 }
139
140 int LUKS_encrypt_to_storage(char *src, size_t srcLength,
141 const char *cipher,
142 const char *cipher_mode,
143 struct volume_key *vk,
144 unsigned int sector,
145 struct crypt_device *ctx)
146 {
147 struct device *device = crypt_metadata_device(ctx);
148 struct crypt_storage *s;
149 int devfd, r = 0;
150
151 /* Only whole sector writes supported */
152 if (MISALIGNED_512(srcLength))
153 return -EINVAL;
154
155 /* Encrypt buffer */
156 r = crypt_storage_init(&s, SECTOR_SIZE, cipher, cipher_mode, vk->key, vk->keylength, false);
157
158 if (r)
159 log_dbg(ctx, "Userspace crypto wrapper cannot use %s-%s (%d).",
160 cipher, cipher_mode, r);
161
162 /* Fallback to old temporary dmcrypt device */
163 if (r == -ENOTSUP || r == -ENOENT)
164 return LUKS_endec_template(src, srcLength, cipher, cipher_mode,
165 vk, sector, write_blockwise, O_RDWR, ctx);
166
167 if (r) {
168 _error_hint(ctx, device_path(device), cipher, cipher_mode,
169 vk->keylength * 8);
170 return r;
171 }
172
173 log_dbg(ctx, "Using userspace crypto wrapper to access keyslot area.");
174
175 r = crypt_storage_encrypt(s, 0, srcLength, src);
176 crypt_storage_destroy(s);
177
178 if (r)
179 return r;
180
181 r = -EIO;
182
183 /* Write buffer to device */
184 if (device_is_locked(device))
185 devfd = device_open_locked(ctx, device, O_RDWR);
186 else
187 devfd = device_open(ctx, device, O_RDWR);
188 if (devfd < 0)
189 goto out;
190
191 if (write_lseek_blockwise(devfd, device_block_size(ctx, device),
192 device_alignment(device), src, srcLength,
193 sector * SECTOR_SIZE) < 0)
194 goto out;
195
196 r = 0;
197 out:
198 device_sync(ctx, device);
199 if (r)
200 log_err(ctx, _("IO error while encrypting keyslot."));
201
202 return r;
203 }
204
205 int LUKS_decrypt_from_storage(char *dst, size_t dstLength,
206 const char *cipher,
207 const char *cipher_mode,
208 struct volume_key *vk,
209 unsigned int sector,
210 struct crypt_device *ctx)
211 {
212 struct device *device = crypt_metadata_device(ctx);
213 struct crypt_storage *s;
214 struct stat st;
215 int devfd, r = 0;
216
217 /* Only whole sector reads supported */
218 if (MISALIGNED_512(dstLength))
219 return -EINVAL;
220
221 r = crypt_storage_init(&s, SECTOR_SIZE, cipher, cipher_mode, vk->key, vk->keylength, false);
222
223 if (r)
224 log_dbg(ctx, "Userspace crypto wrapper cannot use %s-%s (%d).",
225 cipher, cipher_mode, r);
226
227 /* Fallback to old temporary dmcrypt device */
228 if (r == -ENOTSUP || r == -ENOENT)
229 return LUKS_endec_template(dst, dstLength, cipher, cipher_mode,
230 vk, sector, read_blockwise, O_RDONLY, ctx);
231
232 if (r) {
233 _error_hint(ctx, device_path(device), cipher, cipher_mode,
234 vk->keylength * 8);
235 return r;
236 }
237
238 log_dbg(ctx, "Using userspace crypto wrapper to access keyslot area.");
239
240 /* Read buffer from device */
241 if (device_is_locked(device))
242 devfd = device_open_locked(ctx, device, O_RDONLY);
243 else
244 devfd = device_open(ctx, device, O_RDONLY);
245 if (devfd < 0) {
246 log_err(ctx, _("Cannot open device %s."), device_path(device));
247 crypt_storage_destroy(s);
248 return -EIO;
249 }
250
251 if (read_lseek_blockwise(devfd, device_block_size(ctx, device),
252 device_alignment(device), dst, dstLength,
253 sector * SECTOR_SIZE) < 0) {
254 if (!fstat(devfd, &st) && (st.st_size < (off_t)dstLength))
255 log_err(ctx, _("Device %s is too small."), device_path(device));
256 else
257 log_err(ctx, _("IO error while decrypting keyslot."));
258
259 crypt_storage_destroy(s);
260 return -EIO;
261 }
262
263 /* Decrypt buffer */
264 r = crypt_storage_decrypt(s, 0, dstLength, dst);
265 crypt_storage_destroy(s);
266
267 return r;
268 }