]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/cryptsetup/cryptsetup-util.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
5 #include "cryptsetup-util.h"
7 #include "format-util.h"
8 #include "memory-util.h"
10 #include "stat-util.h"
13 #define KEY_FILE_SIZE_MAX (16U*1024U*1024U) /* 16 MiB */
19 uint64_t key_file_offset
,
21 size_t *ret_key_size
) {
23 _cleanup_(erase_and_freep
) char *buffer
= NULL
;
24 _cleanup_free_
char *discovered_path
= NULL
;
25 _cleanup_close_
int fd
= -1;
33 if (strv_isempty(search_path
) || path_is_absolute(key_file
)) {
34 fd
= open(key_file
, O_RDONLY
|O_CLOEXEC
);
36 return log_error_errno(errno
, "Failed to load key file '%s': %m", key_file
);
40 STRV_FOREACH(i
, search_path
) {
41 _cleanup_free_
char *joined
;
43 joined
= path_join(*i
, key_file
);
47 fd
= open(joined
, O_RDONLY
|O_CLOEXEC
);
49 discovered_path
= TAKE_PTR(joined
);
53 return log_error_errno(errno
, "Failed to load key file '%s': %m", joined
);
56 if (!discovered_path
) {
57 /* Search path supplied, but file not found, report by returning NULL, but not failing */
64 key_file
= discovered_path
;
67 if (key_file_size
== 0) {
70 if (fstat(fd
, &st
) < 0)
71 return log_error_errno(errno
, "Failed to stat key file '%s': %m", key_file
);
73 r
= stat_verify_regular(&st
);
75 return log_error_errno(r
, "Key file is not a regular file: %m");
78 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "Key file is empty, refusing.");
79 if ((uint64_t) st
.st_size
> KEY_FILE_SIZE_MAX
) {
80 char buf1
[FORMAT_BYTES_MAX
], buf2
[FORMAT_BYTES_MAX
];
81 return log_error_errno(SYNTHETIC_ERRNO(ERANGE
),
82 "Key file larger (%s) than allowed maximum size (%s), refusing.",
83 format_bytes(buf1
, sizeof(buf1
), st
.st_size
),
84 format_bytes(buf2
, sizeof(buf2
), KEY_FILE_SIZE_MAX
));
87 if (key_file_offset
>= (uint64_t) st
.st_size
)
88 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "Key file offset too large for file, refusing.");
90 key_file_size
= st
.st_size
- key_file_offset
;
93 buffer
= malloc(key_file_size
);
97 if (key_file_offset
> 0)
98 n
= pread(fd
, buffer
, key_file_size
, key_file_offset
);
100 n
= read(fd
, buffer
, key_file_size
);
102 return log_error_errno(errno
, "Failed to read key file '%s': %m", key_file
);
104 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "Empty encrypted key found, refusing.");
106 *ret_key
= TAKE_PTR(buffer
);
107 *ret_key_size
= (size_t) n
;