mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-06 16:30:04 +01:00
Compare commits
372 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
59cf9969f9 | ||
|
|
98ec1e314a | ||
|
|
a9b327c12a | ||
|
|
eaa93a8116 | ||
|
|
018494b6b3 | ||
|
|
3d7a0f741a | ||
|
|
3858b1815c | ||
|
|
4eca4e8fce | ||
|
|
39abe23e0e | ||
|
|
80faafea48 | ||
|
|
f658ea6ba4 | ||
|
|
fa0a24f726 | ||
|
|
24abdf4e72 | ||
|
|
677572a425 | ||
|
|
30d6a8a8f9 | ||
|
|
9fc40d35d3 | ||
|
|
5a032abc33 | ||
|
|
6df6c0a363 | ||
|
|
e2e57e5776 | ||
|
|
3d8cb44c61 | ||
|
|
05dad56f75 | ||
|
|
69361fec1c | ||
|
|
4e0398aef0 | ||
|
|
51ab9da665 | ||
|
|
855a232403 | ||
|
|
96241cea6a | ||
|
|
9e5c87b449 | ||
|
|
7d1b40a3a6 | ||
|
|
969be38a7a | ||
|
|
93382071a5 | ||
|
|
426a8b9df0 | ||
|
|
83811b5ea9 | ||
|
|
56a01574ff | ||
|
|
c68cd0a483 | ||
|
|
b2135a75e2 | ||
|
|
91e8f5ffd9 | ||
|
|
855628f796 | ||
|
|
db8ce3f818 | ||
|
|
973474503a | ||
|
|
4e2561df6d | ||
|
|
b01ec20703 | ||
|
|
ca1b41cf96 | ||
|
|
7825e0d4a6 | ||
|
|
c8c28cf6dd | ||
|
|
fb8aa6d03b | ||
|
|
207383782a | ||
|
|
f25a1c92ec | ||
|
|
44a9e7aa62 | ||
|
|
27eee9cfcb | ||
|
|
196477d194 | ||
|
|
1e68d73bc3 | ||
|
|
17bb1e2fdd | ||
|
|
ba7fd45ba6 | ||
|
|
7058b81bb6 | ||
|
|
b40018860b | ||
|
|
e97ac9f58c | ||
|
|
75447d0d80 | ||
|
|
c760ae36ea | ||
|
|
dbd20776bc | ||
|
|
3ebbceaef2 | ||
|
|
d733e4d0e8 | ||
|
|
4d6d6edcff | ||
|
|
1380efa1c6 | ||
|
|
bce9d695e3 | ||
|
|
bea6e0da74 | ||
|
|
e064406f85 | ||
|
|
3d58f480ee | ||
|
|
660edf7959 | ||
|
|
312efd8582 | ||
|
|
ec657332c6 | ||
|
|
e123263975 | ||
|
|
e8f2bb4a1a | ||
|
|
6e71e2d6ed | ||
|
|
2f6698d1a7 | ||
|
|
d20929194f | ||
|
|
0a6f89cfa6 | ||
|
|
c74f17c6e7 | ||
|
|
616dd5a304 | ||
|
|
79442539c7 | ||
|
|
92b24fd758 | ||
|
|
4a43a2773a | ||
|
|
74c943c352 | ||
|
|
bc49c83ace | ||
|
|
ed28583f17 | ||
|
|
5345a73ca0 | ||
|
|
36f424ce71 | ||
|
|
a757d84b91 | ||
|
|
255464b0ae | ||
|
|
4c350f4d72 | ||
|
|
7cca38632f | ||
|
|
d8bbfb118b | ||
|
|
178bc9ee39 | ||
|
|
7d4d1baaa7 | ||
|
|
f82c1bf90f | ||
|
|
8d856d4e17 | ||
|
|
fb49d9630d | ||
|
|
7866e71d6f | ||
|
|
d2ee949d88 | ||
|
|
3a29cbbf5d | ||
|
|
51bf5435f9 | ||
|
|
505effe085 | ||
|
|
82f8fb653c | ||
|
|
829a2379a1 | ||
|
|
b5894ce1ab | ||
|
|
1bc6caceb1 | ||
|
|
78f33946f1 | ||
|
|
0d90efac88 | ||
|
|
82490aaaa3 | ||
|
|
782f4c5029 | ||
|
|
d63d399c17 | ||
|
|
745c75b5b0 | ||
|
|
1d615cf6dd | ||
|
|
7f0ddcbed4 | ||
|
|
efa7c4574c | ||
|
|
e2b4479543 | ||
|
|
7c23bdb868 | ||
|
|
fa5d46592e | ||
|
|
e5e09d889b | ||
|
|
7dbd007ac1 | ||
|
|
dbb80e41c7 | ||
|
|
33cc4739da | ||
|
|
5518198f97 | ||
|
|
1a81925764 | ||
|
|
15df5904f2 | ||
|
|
07a06f2f40 | ||
|
|
fd94f036c1 | ||
|
|
03607db1f8 | ||
|
|
c2fcc7aebd | ||
|
|
8dbb72e296 | ||
|
|
513e88fd77 | ||
|
|
8360a85169 | ||
|
|
b56a450a31 | ||
|
|
569b485d02 | ||
|
|
bd888e30a6 | ||
|
|
b86c51afeb | ||
|
|
56f47d3899 | ||
|
|
284672c081 | ||
|
|
6f6b54a5fd | ||
|
|
154c344115 | ||
|
|
cccb7780ec | ||
|
|
aa762d5cc1 | ||
|
|
68cc46fc22 | ||
|
|
06bd23d120 | ||
|
|
2f4990868e | ||
|
|
03213ac230 | ||
|
|
fb1b287773 | ||
|
|
7ceaf3f313 | ||
|
|
3f20b04e42 | ||
|
|
82e6ca7202 | ||
|
|
8a170d0e80 | ||
|
|
72be05c817 | ||
|
|
b79ccb782b | ||
|
|
9c8c636ece | ||
|
|
63a5bd5ef6 | ||
|
|
e75f5de2ed | ||
|
|
6df1a69430 | ||
|
|
e7ca35091c | ||
|
|
03ecfe3478 | ||
|
|
f5bf9ef9fa | ||
|
|
f61eb8b427 | ||
|
|
a4f78e1c98 | ||
|
|
d1c3ad2703 | ||
|
|
d7279eeda1 | ||
|
|
9c2d918474 | ||
|
|
16aec64d1b | ||
|
|
04d2ff7689 | ||
|
|
0cd7cac03f | ||
|
|
b2c1ec2f83 | ||
|
|
a15008d876 | ||
|
|
ac535923e0 | ||
|
|
f695e155ec | ||
|
|
9412d9a0f1 | ||
|
|
57eba0d6f5 | ||
|
|
4a9862a666 | ||
|
|
74e94e7bdd | ||
|
|
72cd628357 | ||
|
|
45367e4a34 | ||
|
|
7d76831250 | ||
|
|
d2ff3fc2ee | ||
|
|
537b8454a4 | ||
|
|
a7c71b90b1 | ||
|
|
e0be3deb3a | ||
|
|
5490476d84 | ||
|
|
90865eb887 | ||
|
|
157f71d78e | ||
|
|
176fee54e4 | ||
|
|
61f4363ed7 | ||
|
|
86cc67e081 | ||
|
|
dcc9888350 | ||
|
|
6af6a424b4 | ||
|
|
e1ceb63023 | ||
|
|
4eb7193a27 | ||
|
|
e6ff3b37a4 | ||
|
|
c3e095969f | ||
|
|
2e345a1059 | ||
|
|
e759ebe0bd | ||
|
|
533b874590 | ||
|
|
780ebb4680 | ||
|
|
02a579af59 | ||
|
|
9bcf1c4b8d | ||
|
|
dec9b4f7c7 | ||
|
|
4701842829 | ||
|
|
488b4bdbe8 | ||
|
|
c8d886b422 | ||
|
|
a83bbd2e92 | ||
|
|
c3a47cb72f | ||
|
|
0971e55d4d | ||
|
|
6f45c7a8ac | ||
|
|
c567d852a5 | ||
|
|
0b38128e21 | ||
|
|
b9daa8b2ee | ||
|
|
878c7173c3 | ||
|
|
f69b980dcf | ||
|
|
33378792ca | ||
|
|
c7a2b4d5e3 | ||
|
|
4a077fc2c9 | ||
|
|
f309ec21d7 | ||
|
|
e261cf7481 | ||
|
|
fa8390b23e | ||
|
|
af89858d47 | ||
|
|
e6a3569743 | ||
|
|
604abec333 | ||
|
|
790666ffb0 | ||
|
|
c9f6ccff9f | ||
|
|
02b3f42500 | ||
|
|
e10724accb | ||
|
|
5b68dec43a | ||
|
|
9d13da0050 | ||
|
|
1e94425279 | ||
|
|
fc48f9bc08 | ||
|
|
2eb25910a1 | ||
|
|
1dab341b33 | ||
|
|
1f7ed87e6c | ||
|
|
c59ea422cc | ||
|
|
0bcb71f742 | ||
|
|
7e38a3386e | ||
|
|
c25b5ef215 | ||
|
|
72fb507de2 | ||
|
|
45c4c95b98 | ||
|
|
e8861d1043 | ||
|
|
c48fcb743b | ||
|
|
d5d732ddf4 | ||
|
|
f83bd5cdf6 | ||
|
|
76c87c628f | ||
|
|
fa125a354d | ||
|
|
f184b54796 | ||
|
|
75925fb2f7 | ||
|
|
b780228ade | ||
|
|
91c012eff0 | ||
|
|
05d45c6948 | ||
|
|
a2c13fbc48 | ||
|
|
16c7aab99b | ||
|
|
0cf5e309a0 | ||
|
|
b5fbd682f2 | ||
|
|
90e04b0046 | ||
|
|
329f6562c2 | ||
|
|
852bad1ef4 | ||
|
|
aa44a61ab2 | ||
|
|
3e237cb490 | ||
|
|
7b206fb13d | ||
|
|
8f7e898341 | ||
|
|
7499d9f245 | ||
|
|
ba6e6f051a | ||
|
|
d4f4dfb54f | ||
|
|
3e7dedaf99 | ||
|
|
f18cd7ae81 | ||
|
|
0ae4fcf8eb | ||
|
|
d3d1e30c7c | ||
|
|
47d0cf495d | ||
|
|
2e883f9d91 | ||
|
|
af0c30e3ea | ||
|
|
da5a35356a | ||
|
|
d98cc3bb6c | ||
|
|
9697f17b9d | ||
|
|
ce3a9d172d | ||
|
|
4448ddc488 | ||
|
|
b77d3c66ae | ||
|
|
2debdfead5 | ||
|
|
b168c65fa1 | ||
|
|
2b46d171db | ||
|
|
64c131d132 | ||
|
|
678a251858 | ||
|
|
bf9d2f6cb0 | ||
|
|
61f5dcb11e | ||
|
|
e4387d2bd1 | ||
|
|
48906f354e | ||
|
|
1ddc098e43 | ||
|
|
165e6c234c | ||
|
|
1be631f43f | ||
|
|
f5f34c2f50 | ||
|
|
33f3619e98 | ||
|
|
3720b66d00 | ||
|
|
864bbc5472 | ||
|
|
080566a1fd | ||
|
|
d9766037a3 | ||
|
|
02821adc47 | ||
|
|
7b08fd4b7d | ||
|
|
0505c70be2 | ||
|
|
f247038e65 | ||
|
|
d7667e9e6e | ||
|
|
188cb114af | ||
|
|
35c49ababf | ||
|
|
faafe09bd0 | ||
|
|
a0e87c9420 | ||
|
|
d9d39f1812 | ||
|
|
82af225742 | ||
|
|
919f4df1a7 | ||
|
|
71a1698bf2 | ||
|
|
a987dd95b8 | ||
|
|
ab6ab8e65c | ||
|
|
3b28d66410 | ||
|
|
eee46ef2f4 | ||
|
|
3c189b4183 | ||
|
|
fd5ab0edf7 | ||
|
|
420387a7a5 | ||
|
|
fc740f8b6d | ||
|
|
834059ddfa | ||
|
|
5ec2fbcd38 | ||
|
|
2fbf5cd79f | ||
|
|
64ebe95751 | ||
|
|
77109b3a33 | ||
|
|
b43429e684 | ||
|
|
97e39f0744 | ||
|
|
fad592b512 | ||
|
|
565de3c536 | ||
|
|
c802269ea3 | ||
|
|
06268963fb | ||
|
|
2227797691 | ||
|
|
f0888c1fe0 | ||
|
|
eda2e62589 | ||
|
|
494d8ec04c | ||
|
|
bb8088ca0f | ||
|
|
26f4bc39fc | ||
|
|
025e4d9fc6 | ||
|
|
b2774d57ba | ||
|
|
51edfb4ec9 | ||
|
|
79019b1ced | ||
|
|
bc87140b5b | ||
|
|
1c5251069b | ||
|
|
0b6dfefcec | ||
|
|
a9e32c55c0 | ||
|
|
a494228407 | ||
|
|
9932b5fc5c | ||
|
|
966ba44a33 | ||
|
|
62c872eb49 | ||
|
|
434fee2e13 | ||
|
|
d3f829c065 | ||
|
|
83934bdcf3 | ||
|
|
3691add163 | ||
|
|
cc7a9e4607 | ||
|
|
943fa69da6 | ||
|
|
3bef291184 | ||
|
|
7316c53b04 | ||
|
|
5e1d1e1850 | ||
|
|
e52c8e148c | ||
|
|
7eb47f3db1 | ||
|
|
ec59d31d04 | ||
|
|
ddd15b63b2 | ||
|
|
e91b35a53d | ||
|
|
fb4079aa4d | ||
|
|
48b203a134 | ||
|
|
2746fd708f | ||
|
|
684f43d84d | ||
|
|
6b1be52e6b | ||
|
|
de6258d366 | ||
|
|
5e4dbf33be | ||
|
|
b03cb3f3d8 | ||
|
|
e08401a2ec | ||
|
|
0a9e7028ae | ||
|
|
ba0ecc54df | ||
|
|
6920f9dc27 | ||
|
|
ba2547212e |
15
.gitlab/issue_templates/Bug.md
Normal file
15
.gitlab/issue_templates/Bug.md
Normal file
@@ -0,0 +1,15 @@
|
||||
### Issue description
|
||||
<!-- Please, shortly describe the issue here. -->
|
||||
|
||||
### Steps for reproducing the issue
|
||||
<!-- How it can be reproduced? Include all important steps. -->
|
||||
|
||||
### Additional info
|
||||
<!-- Please mention what distribution you are using. -->
|
||||
|
||||
### Debug log
|
||||
<!-- Paste a debug log of the failing command (add --debug option) between the markers below (to keep raw debug format).-->
|
||||
```
|
||||
Output with --debug option:
|
||||
|
||||
```
|
||||
5
.gitlab/issue_templates/Documentation.md
Normal file
5
.gitlab/issue_templates/Documentation.md
Normal file
@@ -0,0 +1,5 @@
|
||||
### Documentation issue
|
||||
<!-- Please, shortly describe the issue in documentation here. -->
|
||||
|
||||
### Additional info
|
||||
<!-- Please mention what cryptsetup version you are using. -->
|
||||
5
.gitlab/issue_templates/Feature.md
Normal file
5
.gitlab/issue_templates/Feature.md
Normal file
@@ -0,0 +1,5 @@
|
||||
### New feature description
|
||||
<!-- Please, shortly describe the requested feature here. -->
|
||||
|
||||
### Additional info
|
||||
<!-- Please mention what distribution and cryptsetup version you are using. -->
|
||||
@@ -102,7 +102,13 @@ function travis_install_script
|
||||
keyutils \
|
||||
libjson-c-dev \
|
||||
libblkid-dev \
|
||||
dkms \
|
||||
linux-headers-$(uname -r) \
|
||||
linux-modules-extra-$(uname -r) \
|
||||
|| return
|
||||
|
||||
# For VeraCrypt test
|
||||
sudo apt-get install gost-crypto-dkms
|
||||
}
|
||||
|
||||
function travis_before_script
|
||||
|
||||
10
.travis.yml
10
.travis.yml
@@ -1,21 +1,23 @@
|
||||
language: c
|
||||
|
||||
sudo: required
|
||||
dist: xenial
|
||||
os: linux
|
||||
dist: focal
|
||||
group: edge
|
||||
|
||||
compiler:
|
||||
- gcc
|
||||
|
||||
env:
|
||||
- MAKE_CHECK="gcrypt"
|
||||
# MAKE_CHECK="gcrypt"
|
||||
- MAKE_CHECK="openssl"
|
||||
- MAKE_CHECK="kernel"
|
||||
# MAKE_CHECK="kernel"
|
||||
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- wip-luks2
|
||||
- v2_0_x
|
||||
- v2.3.x
|
||||
|
||||
before_install:
|
||||
- uname -a
|
||||
|
||||
5
README
5
README
@@ -14,7 +14,8 @@ FAQ:
|
||||
MAILING LIST:
|
||||
|
||||
E-MAIL: dm-crypt@saout.de
|
||||
URL: http://www.saout.de/mailman/listinfo/dm-crypt
|
||||
URL: https://www.saout.de/mailman/listinfo/dm-crypt
|
||||
ARCHIVE: https://lore.kernel.org/dm-crypt/
|
||||
|
||||
DOWNLOAD:
|
||||
|
||||
@@ -28,4 +29,4 @@ SOURCE CODE:
|
||||
NLS (PO TRANSLATIONS):
|
||||
|
||||
PO files are maintained by:
|
||||
http://translationproject.org/domain/cryptsetup.html
|
||||
https://translationproject.org/domain/cryptsetup.html
|
||||
|
||||
21
README.md
21
README.md
@@ -5,8 +5,8 @@ What the ...?
|
||||
**Cryptsetup** is a utility used to conveniently set up disk encryption based
|
||||
on the [DMCrypt](https://gitlab.com/cryptsetup/cryptsetup/wikis/DMCrypt) kernel module.
|
||||
|
||||
These include **plain** **dm-crypt** volumes, **LUKS** volumes, **loop-AES**
|
||||
and **TrueCrypt** (including **VeraCrypt** extension) formats.
|
||||
These include **plain** **dm-crypt** volumes, **LUKS** volumes, **loop-AES**,
|
||||
**TrueCrypt** (including **VeraCrypt** extension) and **BitLocker** formats.
|
||||
|
||||
The project also includes a **veritysetup** utility used to conveniently setup
|
||||
[DMVerity](https://gitlab.com/cryptsetup/cryptsetup/wikis/DMVerity) block integrity checking kernel module
|
||||
@@ -44,16 +44,13 @@ Download
|
||||
--------
|
||||
All release tarballs and release notes are hosted on [kernel.org](https://www.kernel.org/pub/linux/utils/cryptsetup/).
|
||||
|
||||
**The latest cryptsetup version is 2.2.2**
|
||||
* [cryptsetup-2.2.2.tar.xz](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.2/cryptsetup-2.2.2.tar.xz)
|
||||
* Signature [cryptsetup-2.2.2.tar.sign](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.2/cryptsetup-2.2.2.tar.sign)
|
||||
**The latest stable cryptsetup version is 2.3.5**
|
||||
* [cryptsetup-2.3.5.tar.xz](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.3/cryptsetup-2.3.5.tar.xz)
|
||||
* Signature [cryptsetup-2.3.5.tar.sign](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.3/cryptsetup-2.3.5.tar.sign)
|
||||
_(You need to decompress file first to check signature.)_
|
||||
* [Cryptsetup 2.2.2 Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.2/v2.2.2-ReleaseNotes).
|
||||
* [Cryptsetup 2.3.5 Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.3/v2.3.5-ReleaseNotes).
|
||||
|
||||
Previous versions
|
||||
* [Version 2.2.1](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.2/cryptsetup-2.2.1.tar.xz) -
|
||||
[Signature](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.2/cryptsetup-2.2.1.tar.sign) -
|
||||
[Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.2/v2.2.0-ReleaseNotes).
|
||||
* [Version 2.0.6](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/cryptsetup-2.0.6.tar.xz) -
|
||||
[Signature](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/cryptsetup-2.0.6.tar.sign) -
|
||||
[Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/v2.0.6-ReleaseNotes).
|
||||
@@ -70,7 +67,7 @@ For libcryptsetup documentation see [libcryptsetup API](https://mbroz.fedorapeop
|
||||
|
||||
The libcryptsetup API/ABI changes are tracked in [compatibility report](https://abi-laboratory.pro/tracker/timeline/cryptsetup/).
|
||||
|
||||
NLS PO files are maintained by [TranslationProject](http://translationproject.org/domain/cryptsetup.html).
|
||||
NLS PO files are maintained by [TranslationProject](https://translationproject.org/domain/cryptsetup.html).
|
||||
|
||||
Help!
|
||||
-----
|
||||
@@ -79,5 +76,5 @@ For cryptsetup and LUKS related questions, please use the dm-crypt mailing list,
|
||||
|
||||
If you want to subscribe just send an empty mail to [dm-crypt-subscribe@saout.de](mailto:dm-crypt-subscribe@saout.de).
|
||||
|
||||
You can also browse [list archive](http://www.saout.de/pipermail/dm-crypt/) or read it through
|
||||
[web interface](https://marc.info/?l=dm-crypt).
|
||||
You can also browse [list archive](https://www.saout.de/pipermail/dm-crypt/) or read and search it through
|
||||
[web interface on lore.kernel.org](https://lore.kernel.org/dm-crypt/) or alternatively on [marc.info](https://marc.info/?l=dm-crypt).
|
||||
|
||||
25
autogen.sh
25
autogen.sh
@@ -9,16 +9,23 @@ DIE=0
|
||||
(autopoint --version) < /dev/null > /dev/null 2>&1 || {
|
||||
echo
|
||||
echo "**Error**: You must have autopoint installed."
|
||||
echo "Download the appropriate package for your distribution,"
|
||||
echo "or see http://www.gnu.org/software/gettext"
|
||||
echo "Download the appropriate package for your distribution."
|
||||
DIE=1
|
||||
}
|
||||
|
||||
|
||||
(msgfmt --version) < /dev/null > /dev/null 2>&1 || {
|
||||
echo
|
||||
echo "**Warning**: You should have gettext installed."
|
||||
echo "Download the appropriate package for your distribution."
|
||||
echo "To disable translation, you can also use --disable-nls"
|
||||
echo "configure option."
|
||||
}
|
||||
|
||||
(autoconf --version) < /dev/null > /dev/null 2>&1 || {
|
||||
echo
|
||||
echo "**Error**: You must have autoconf installed to."
|
||||
echo "Download the appropriate package for your distribution,"
|
||||
echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/"
|
||||
echo "**Error**: You must have autoconf installed."
|
||||
echo "Download the appropriate package for your distribution."
|
||||
DIE=1
|
||||
}
|
||||
|
||||
@@ -26,8 +33,7 @@ DIE=0
|
||||
(libtool --version) < /dev/null > /dev/null 2>&1 || {
|
||||
echo
|
||||
echo "**Error**: You must have libtool installed."
|
||||
echo "Get ftp://ftp.gnu.org/pub/gnu/"
|
||||
echo "(or a newer version if it is available)"
|
||||
echo "Download the appropriate package for your distribution."
|
||||
DIE=1
|
||||
}
|
||||
}
|
||||
@@ -35,8 +41,7 @@ DIE=0
|
||||
(automake --version) < /dev/null > /dev/null 2>&1 || {
|
||||
echo
|
||||
echo "**Error**: You must have automake installed."
|
||||
echo "Get ftp://ftp.gnu.org/pub/gnu/"
|
||||
echo "(or a newer version if it is available)"
|
||||
echo "Download the appropriate package for your distribution."
|
||||
DIE=1
|
||||
NO_AUTOMAKE=yes
|
||||
}
|
||||
@@ -47,8 +52,6 @@ test -n "$NO_AUTOMAKE" || (aclocal --version) < /dev/null > /dev/null 2>&1 || {
|
||||
echo
|
||||
echo "**Error**: Missing aclocal. The version of automake"
|
||||
echo "installed doesn't appear recent enough."
|
||||
echo "Get ftp://ftp.gnu.org/pub/gnu/"
|
||||
echo "(or a newer version if it is available)"
|
||||
DIE=1
|
||||
}
|
||||
|
||||
|
||||
31
configure.ac
31
configure.ac
@@ -1,9 +1,9 @@
|
||||
AC_PREREQ([2.67])
|
||||
AC_INIT([cryptsetup],[2.2.2])
|
||||
AC_INIT([cryptsetup],[2.3.5])
|
||||
|
||||
dnl library version from <major>.<minor>.<release>[-<suffix>]
|
||||
LIBCRYPTSETUP_VERSION=$(echo $PACKAGE_VERSION | cut -f1 -d-)
|
||||
LIBCRYPTSETUP_VERSION_INFO=17:0:5
|
||||
LIBCRYPTSETUP_VERSION_INFO=18:0:6
|
||||
|
||||
AM_SILENT_RULES([yes])
|
||||
AC_CONFIG_SRCDIR(src/cryptsetup.c)
|
||||
@@ -33,6 +33,7 @@ AC_PROG_MAKE_SET
|
||||
AC_ENABLE_STATIC(no)
|
||||
LT_INIT
|
||||
PKG_PROG_PKG_CONFIG
|
||||
AM_ICONV
|
||||
|
||||
dnl ==========================================================================
|
||||
dnl define PKG_CHECK_VAR for old pkg-config <= 0.28
|
||||
@@ -56,8 +57,15 @@ dnl ==========================================================================
|
||||
AC_C_RESTRICT
|
||||
|
||||
AC_HEADER_DIRENT
|
||||
AC_HEADER_STDC
|
||||
AC_CHECK_HEADERS(fcntl.h malloc.h inttypes.h sys/ioctl.h sys/mman.h \
|
||||
sys/sysmacros.h sys/statvfs.h ctype.h unistd.h locale.h byteswap.h endian.h stdint.h)
|
||||
AC_CHECK_DECLS([O_CLOEXEC],,[AC_DEFINE([O_CLOEXEC],[0], [Defined to 0 if not provided])],
|
||||
[[
|
||||
#ifdef HAVE_FCNTL_H
|
||||
# include <fcntl.h>
|
||||
#endif
|
||||
]])
|
||||
|
||||
AC_CHECK_HEADERS(uuid/uuid.h,,[AC_MSG_ERROR([You need the uuid library.])])
|
||||
AC_CHECK_HEADER(libdevmapper.h,,[AC_MSG_ERROR([You need the device-mapper library.])])
|
||||
@@ -138,14 +146,6 @@ AC_DEFUN([NO_FIPS], [
|
||||
fi
|
||||
])
|
||||
|
||||
dnl LUKS2 online reencryption
|
||||
AC_ARG_ENABLE([luks2-reencryption],
|
||||
AS_HELP_STRING([--disable-luks2-reencryption], [disable LUKS2 online reencryption extension]),
|
||||
[], [enable_luks2_reencryption=yes])
|
||||
if test "x$enable_luks2_reencryption" = "xyes"; then
|
||||
AC_DEFINE(USE_LUKS2_REENCRYPTION, 1, [Use LUKS2 online reencryption extension])
|
||||
fi
|
||||
|
||||
dnl ==========================================================================
|
||||
dnl pwquality library (cryptsetup CLI only)
|
||||
AC_ARG_ENABLE([pwquality],
|
||||
@@ -176,7 +176,15 @@ AC_DEFINE_UNQUOTED([PASSWDQC_CONFIG_FILE], ["$use_passwdqc_config"], [passwdqc l
|
||||
if test "x$enable_passwdqc" = "xyes"; then
|
||||
AC_DEFINE(ENABLE_PASSWDQC, 1, [Enable password quality checking using passwdqc library])
|
||||
|
||||
PASSWDQC_LIBS="-lpasswdqc"
|
||||
saved_LIBS="$LIBS"
|
||||
AC_SEARCH_LIBS([passwdqc_check], [passwdqc])
|
||||
case "$ac_cv_search_passwdqc_check" in
|
||||
no) AC_MSG_ERROR([failed to find passwdqc_check]) ;;
|
||||
-l*) PASSWDQC_LIBS="$ac_cv_search_passwdqc_check" ;;
|
||||
*) PASSWDQC_LIBS= ;;
|
||||
esac
|
||||
AC_CHECK_FUNCS([passwdqc_params_free])
|
||||
LIBS="$saved_LIBS"
|
||||
fi
|
||||
|
||||
if test "x$enable_pwquality$enable_passwdqc" = "xyesyes"; then
|
||||
@@ -355,6 +363,7 @@ AC_CHECK_DECLS([dm_task_retry_remove], [], [], [#include <libdevmapper.h>])
|
||||
AC_CHECK_DECLS([dm_task_deferred_remove], [], [], [#include <libdevmapper.h>])
|
||||
AC_CHECK_DECLS([dm_device_has_mounted_fs], [], [], [#include <libdevmapper.h>])
|
||||
AC_CHECK_DECLS([dm_device_has_holders], [], [], [#include <libdevmapper.h>])
|
||||
AC_CHECK_DECLS([dm_device_get_name], [], [], [#include <libdevmapper.h>])
|
||||
AC_CHECK_DECLS([DM_DEVICE_GET_TARGET_VERSION], [], [], [#include <libdevmapper.h>])
|
||||
AC_CHECK_DECLS([DM_UDEV_DISABLE_DISK_RULES_FLAG], [have_cookie=yes], [have_cookie=no], [#include <libdevmapper.h>])
|
||||
if test "x$enable_udev" = xyes; then
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* libcryptsetup API log example
|
||||
*
|
||||
* Copyright (C) 2011-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2011-2021 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* libcryptsetup API - using LUKS device example
|
||||
*
|
||||
* Copyright (C) 2011-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2011-2021 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
||||
209
docs/v2.3.0-ReleaseNotes
Normal file
209
docs/v2.3.0-ReleaseNotes
Normal file
@@ -0,0 +1,209 @@
|
||||
Cryptsetup 2.3.0 Release Notes
|
||||
==============================
|
||||
Stable release with new experimental features and bug fixes.
|
||||
|
||||
Cryptsetup 2.3 version introduces support for BitLocker-compatible
|
||||
devices (BITLK format). This format is used in Windows systems,
|
||||
and in combination with a filesystem driver, cryptsetup now provides
|
||||
native read-write access to BitLocker Full Disk Encryption devices.
|
||||
|
||||
The BITLK implementation is based on publicly available information
|
||||
and it is an independent and opensource implementation that allows
|
||||
to access this proprietary disk encryption.
|
||||
|
||||
Changes since version 2.2.2
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* BITLK (Windows BitLocker compatible) device access
|
||||
|
||||
BITLK userspace implementation is based on the master thesis and code
|
||||
provided by Vojtech Trefny. Also, thanks to other opensource projects
|
||||
like libbde (that provide alternative approach to decode this format)
|
||||
we were able to verify cryptsetup implementation.
|
||||
|
||||
NOTE: Support for the BITLK device is EXPERIMENTAL and will require
|
||||
a lot of testing. If you get some error message (mainly unsupported
|
||||
metadata in the on-disk header), please help us by submitting an issue
|
||||
to cryptsetup project, so we can fix it. Thank you!
|
||||
|
||||
Cryptsetup supports BITLK activation through passphrase or recovery
|
||||
passphrase for existing devices (BitLocker and Bitlocker to Go).
|
||||
|
||||
Activation through TPM, SmartCard, or any other key protector
|
||||
is not supported. And in some situations, mainly for TPM bind to some
|
||||
PCR registers, it could be even impossible on Linux in the future.
|
||||
|
||||
All metadata (key protectors) are handled read-only, cryptsetup cannot
|
||||
create or modify them. Except for old devices (created in old Vista
|
||||
systems), all format variants should be recognized.
|
||||
|
||||
Data devices can be activated read-write (followed by mounting through
|
||||
the proper filesystem driver). To access filesystem on the decrypted device
|
||||
you need properly installed driver (vfat, NTFS or exFAT).
|
||||
|
||||
Foe AES-XTS, activation is supported on all recent Linux kernels.
|
||||
|
||||
For older AES-CBC encryption, Linux Kernel version 5.3 is required
|
||||
(support for special IV variant); for AES-CBC with Elephant diffuser,
|
||||
Linux Kernel 5.6 is required.
|
||||
|
||||
Please note that CBC variants are legacy, and we provide it only
|
||||
for backward compatibility (to be able to access old drives).
|
||||
|
||||
Cryptsetup command now supports the new "bitlk" format and implement dump,
|
||||
open, status, and close actions.
|
||||
|
||||
To activate a BITLK device, use
|
||||
|
||||
# cryptsetup open --type bitlk <device> <name>
|
||||
or with alias
|
||||
# cryptsetup bitlkOpen <device> <name>
|
||||
|
||||
Then with properly installed fs driver (usually NTFS, vfat or exFAT),
|
||||
you can mount the plaintext device /dev/mapper<name> device as a common
|
||||
filesystem.
|
||||
|
||||
To print metadata information about BITLK device, use
|
||||
# crypotsetup bitlkDump <device>
|
||||
|
||||
To print information about the active device, use
|
||||
# cryptsetup status <name>
|
||||
|
||||
Example (activation of disk image):
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
# Recent blkid recognizes BitLocker device,just to verity
|
||||
# blkid bitlocker_xts_ntfs.img
|
||||
bitlocker_xts_ntfs.img: TYPE="BitLocker"
|
||||
|
||||
# Print visible metadata information (on-disk, form the image)
|
||||
# cryptsetup bitlkDump bitlocker_xts_ntfs.img
|
||||
Info for BITLK device bitlocker_xts_ntfs.img.
|
||||
Version: 2
|
||||
GUID: ...
|
||||
Created: Wed Oct 23 17:38:15 2019
|
||||
Description: DESKTOP-xxxxxxx E: 23.10.2019
|
||||
Cipher name: aes
|
||||
Cipher mode: xts-plain64
|
||||
Cipher key: 128 bits
|
||||
|
||||
Keyslots:
|
||||
0: VMK
|
||||
GUID: ...
|
||||
Protection: VMK protected with passphrase
|
||||
Salt: ...
|
||||
Key data size: 44 [bytes]
|
||||
1: VMK
|
||||
GUID: ...
|
||||
Protection: VMK protected with recovery passphrase
|
||||
Salt: ...
|
||||
Key data size: 44 [bytes]
|
||||
2: FVEK
|
||||
Key data size: 44 [bytes]
|
||||
|
||||
# Activation (recovery passphrase works the same as password)
|
||||
# cryptsetup bitlkOpen bitlocker_xts_ntfs.img test -v
|
||||
Enter passphrase for bitlocker_xts_ntfs.img:
|
||||
Command successful.
|
||||
|
||||
# Information about the active device
|
||||
# cryptsetup status test
|
||||
/dev/mapper/test is active.
|
||||
type: BITLK
|
||||
cipher: aes-xts-plain64
|
||||
keysize: 128 bits
|
||||
...
|
||||
|
||||
# Plaintext device should now contain decrypted NTFS filesystem
|
||||
# blkid /dev/mapper/test
|
||||
/dev/mapper/test: UUID="..." TYPE="ntfs"
|
||||
|
||||
# And can be mounted
|
||||
# mount /dev/mapper/test /mnt/tst
|
||||
|
||||
# Deactivation
|
||||
# umount /mnt/tst
|
||||
# cryptsetup close test
|
||||
|
||||
* Veritysetup now supports activation with additional PKCS7 signature
|
||||
of root hash through --root-hash-signature option.
|
||||
The signature uses an in-kernel trusted key to validate the signature
|
||||
of the root hash during activation. This option requires Linux kernel
|
||||
5.4 with DM_VERITY_VERIFY_ROOTHASH_SIG option.
|
||||
|
||||
Verity devices activated with signature now has a special flag
|
||||
(with signature) active in device status (veritysetup status <name>).
|
||||
|
||||
Usage:
|
||||
# veritysetup open <data_device> name <hash_device> <root_hash> \
|
||||
--root-hash-signature=<roothash_p7_sig_file>
|
||||
|
||||
* Integritysetup now calculates hash integrity size according to algorithm
|
||||
instead of requiring an explicit tag size.
|
||||
|
||||
Previously, when integritysetup formats a device with hash or
|
||||
HMAC integrity checksums, it required explicitly tag size entry from
|
||||
a user (or used default value).
|
||||
This led to confusion and unexpected shortened tag sizes.
|
||||
|
||||
Now, libcryptsetup calculates tag size according to real hash output.
|
||||
Tag size can also be specified, then it warns if these values differ.
|
||||
|
||||
* Integritysetup now supports fixed padding for dm-integrity devices.
|
||||
|
||||
There was an in-kernel bug that wasted a lot of space when using metadata
|
||||
areas for integrity-protected devices if a larger sector size than
|
||||
512 bytes was used.
|
||||
This problem affects both stand-alone dm-integrity and also LUKS2 with
|
||||
authenticated encryption and larger sector size.
|
||||
|
||||
The new extension to dm-integrity superblock is needed, so devices
|
||||
with the new optimal padding cannot be activated on older systems.
|
||||
|
||||
Integritysetup/Cryptsetup will use new padding automatically if it
|
||||
detects the proper kernel. To create a compatible device with
|
||||
the old padding, use --integrity-legacy-padding option.
|
||||
|
||||
* A lot of fixes to online LUKS2 reecryption.
|
||||
|
||||
* Add crypt_resume_by_volume_key() function to libcryptsetup.
|
||||
If a user has a volume key available, the LUKS device can be resumed
|
||||
directly using the provided volume key.
|
||||
No keyslot derivation is needed, only the key digest is checked.
|
||||
|
||||
* Implement active device suspend info.
|
||||
Add CRYPT_ACTIVATE_SUSPENDED bit to crypt_get_active_device() flags
|
||||
that informs the caller that device is suspended (luksSuspend).
|
||||
|
||||
* Allow --test-passphrase for a detached header.
|
||||
Before this fix, we required a data device specified on the command
|
||||
line even though it was not necessary for the passphrase check.
|
||||
|
||||
* Allow --key-file option in legacy offline encryption.
|
||||
The option was ignored for LUKS1 encryption initialization.
|
||||
|
||||
* Export memory safe functions.
|
||||
To make developing of some extensions simpler, we now export
|
||||
functions to handle memory with proper wipe on deallocation.
|
||||
|
||||
* Fail crypt_keyslot_get_pbkdf for inactive LUKS1 keyslot.
|
||||
|
||||
Libcryptsetup API extensions
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
The libcryptsetup API is backward compatible for existing symbols.
|
||||
|
||||
New symbols
|
||||
crypt_set_compatibility
|
||||
crypt_get_compatibility;
|
||||
crypt_resume_by_volume_key;
|
||||
crypt_activate_by_signed_key;
|
||||
crypt_safe_alloc;
|
||||
crypt_safe_realloc;
|
||||
crypt_safe_free;
|
||||
crypt_safe_memzero;
|
||||
|
||||
New defines introduced :
|
||||
CRYPT_BITLK "BITLK" - BITLK (BitLocker-compatible mode
|
||||
CRYPT_COMPAT_LEGACY_INTEGRITY_PADDING - dm-integrity legacy padding
|
||||
CRYPT_VERITY_ROOT_HASH_SIGNATURE - dm-verity root hash signature
|
||||
CRYPT_ACTIVATE_SUSPENDED - device suspended info flag
|
||||
45
docs/v2.3.1-ReleaseNotes
Normal file
45
docs/v2.3.1-ReleaseNotes
Normal file
@@ -0,0 +1,45 @@
|
||||
Cryptsetup 2.3.1 Release Notes
|
||||
==============================
|
||||
Stable bug-fix release.
|
||||
|
||||
All users of cryptsetup 2.x should upgrade to this version.
|
||||
|
||||
Changes since version 2.3.0
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* Support VeraCrypt 128 bytes passwords.
|
||||
VeraCrypt now allows passwords of maximal length 128 bytes
|
||||
(compared to legacy TrueCrypt where it was limited by 64 bytes).
|
||||
|
||||
* Strip extra newline from BitLocker recovery keys
|
||||
There might be a trailing newline added by the text editor when
|
||||
the recovery passphrase was passed using the --key-file option.
|
||||
|
||||
* Detect separate libiconv library.
|
||||
It should fix compilation issues on distributions with iconv
|
||||
implemented in a separate library.
|
||||
|
||||
* Various fixes and workarounds to build on old Linux distributions.
|
||||
|
||||
* Split lines with hexadecimal digest printing for large key-sizes.
|
||||
|
||||
* Do not wipe the device with no integrity profile.
|
||||
With --integrity none we performed useless full device wipe.
|
||||
|
||||
* Workaround for dm-integrity kernel table bug.
|
||||
Some kernels show an invalid dm-integrity mapping table
|
||||
if superblock contains the "recalculate" bit. This causes
|
||||
integritysetup to not recognize the dm-integrity device.
|
||||
Integritysetup now specifies kernel options such a way that
|
||||
even on unpatched kernels mapping table is correct.
|
||||
|
||||
* Print error message if LUKS1 keyslot cannot be processed.
|
||||
If the crypto backend is missing support for hash algorithms
|
||||
used in PBKDF2, the error message was not visible.
|
||||
|
||||
* Properly align LUKS2 keyslots area on conversion.
|
||||
If the LUKS1 payload offset (data offset) is not aligned
|
||||
to 4 KiB boundary, new LUKS2 keyslots area in now aligned properly.
|
||||
|
||||
* Validate LUKS2 earlier on conversion to not corrupt the device
|
||||
if binary keyslots areas metadata are not correct.
|
||||
42
docs/v2.3.2-ReleaseNotes
Normal file
42
docs/v2.3.2-ReleaseNotes
Normal file
@@ -0,0 +1,42 @@
|
||||
Cryptsetup 2.3.2 Release Notes
|
||||
==============================
|
||||
Stable bug-fix release.
|
||||
|
||||
All users of cryptsetup 2.x should upgrade to this version.
|
||||
|
||||
Changes since version 2.3.1
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* Support compilation with json-c library version 0.14.
|
||||
|
||||
* Update FAQ document for some LUKS2 specific information.
|
||||
|
||||
* Add option to dump content of LUKS2 unbound keyslot:
|
||||
cryptsetup luksDump --unbound -S <slot> <device>
|
||||
or optionally with --master-key-file option.
|
||||
|
||||
The slot number --key-slot (-S) option is mandatory here.
|
||||
|
||||
An unbound keyslot store a key is that is not assigned to data
|
||||
area on disk (LUKS2 allows to store arbitrary keys).
|
||||
|
||||
* Rephrase some error messages and remove redundant end-of-lines.
|
||||
|
||||
* Add support for discards (TRIM) for standalone dm-integrity devices.
|
||||
Linux kernel 5.7 adds support for optional discard/TRIM operation
|
||||
over dm-integrity devices.
|
||||
|
||||
It is now supported through --allow-discards integritysetup option.
|
||||
Note you need to add this flag in all activation calls.
|
||||
|
||||
Note that this option cannot be used for LUKS2 authenticated encryption
|
||||
(that uses dm-integrity for storing additional per-sector metadata).
|
||||
|
||||
* Fix cryptsetup-reencrypt to work on devices that do not allow
|
||||
direct-io device access.
|
||||
|
||||
* Fix a crash in the BitLocker-compatible code error path.
|
||||
|
||||
* Fix Veracrypt compatible support for longer (>64 bytes) passphrases.
|
||||
It allows some older images to be correctly opened again.
|
||||
The issue was introduced in version 2.3.1.
|
||||
42
docs/v2.3.3-ReleaseNotes
Normal file
42
docs/v2.3.3-ReleaseNotes
Normal file
@@ -0,0 +1,42 @@
|
||||
Cryptsetup 2.3.3 Release Notes
|
||||
==============================
|
||||
Stable bug-fix release.
|
||||
|
||||
All users of cryptsetup 2.x should upgrade to this version.
|
||||
|
||||
Changes since version 2.3.2
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* Fix BitLocker compatible device access that uses native 4kB sectors.
|
||||
|
||||
Devices formatted with storage that natively support 4096-bytes
|
||||
sectors can also use this sector size for encryption units.
|
||||
|
||||
* Support large IV count (--iv-large-sectors) cryptsetup option
|
||||
for plain device mapping.
|
||||
|
||||
The large IV count is supported in dm-crypt together with larger
|
||||
sector encryption. It counts the Initialization Vector (IV) in
|
||||
a larger sector size instead of 512-bytes sectors.
|
||||
|
||||
This option does not have any performance or security impact,
|
||||
but it can be used for accessing incompatible existing disk images
|
||||
from other systems.
|
||||
|
||||
Only open action with plain device type and sector size > 512 bytes
|
||||
are supported.
|
||||
|
||||
* Fix a memory leak in BitLocker compatible handling.
|
||||
|
||||
* Allow EBOIV (Initialization Vector algorithm) use.
|
||||
|
||||
The EBOIV initialization vector is intended to be used internally
|
||||
with BitLocker devices (for CBC mode). It can now be used also
|
||||
outside of the BitLocker compatible code.
|
||||
|
||||
* Require both keyslot cipher and key size options.
|
||||
|
||||
If these LUKS2 keyslot parameters were not specified together,
|
||||
cryptsetup silently failed.
|
||||
|
||||
* Update to man pages and FAQ.
|
||||
112
docs/v2.3.4-ReleaseNotes
Normal file
112
docs/v2.3.4-ReleaseNotes
Normal file
@@ -0,0 +1,112 @@
|
||||
Cryptsetup 2.3.4 Release Notes
|
||||
==============================
|
||||
Stable bug-fix release with a security fix (32-bit only).
|
||||
|
||||
All users of cryptsetup 2.2.x and later should upgrade to this version.
|
||||
|
||||
Changes since version 2.3.3
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* Fix a possible out-of-bounds memory write while validating LUKS2 data
|
||||
segments metadata (CVE-2020-14382).
|
||||
|
||||
This problem can be triggered only on 32-bit builds (64-bit systems
|
||||
are not affected).
|
||||
|
||||
LUKS2 format validation code contains a bug in segments validation code
|
||||
where the code does not check for possible overflow on memory allocation.
|
||||
|
||||
Due to the bug, the libcryptsetup can be tricked to expect such allocation
|
||||
was successful. Later it may read data from image crafted by an attacker and
|
||||
actually write such data beyond allocated memory.
|
||||
|
||||
The bug was introduced in cryptsetup 2.2.0. All later releases until 2.3.4
|
||||
are affected.
|
||||
|
||||
If you only backport the fix for this CVE, these master branch git commits
|
||||
should be backported:
|
||||
52f5cb8cedf22fb3e14c744814ec8af7614146c7
|
||||
46ee71edcd13e1dad50815ad65c28779aa6f7503
|
||||
752c9a52798f11d3b765b673ebaa3058eb25316e
|
||||
|
||||
Thanks to Tobias Stoeckmann for discovering this issue.
|
||||
|
||||
* Ignore reported optimal IO size if not aligned to minimal page size.
|
||||
|
||||
Some USB enclosures report bogus block device topology (see lsblk -t) that
|
||||
prevents LUKS2 format with 4k sector size (reported values are not correctly
|
||||
aligned). The code now ignores such values and uses the default alignment.
|
||||
|
||||
* Added support for new no_read/write_wrokqueue dm-crypt options (kernel 5.9).
|
||||
|
||||
These performance options, introduced in kernel 5.9, configure dm-crypt
|
||||
to bypass read or write workqueues and run encryption synchronously.
|
||||
|
||||
Use --perf-no_read_workqueue or --perf-no_write_workqueue cryptsetup arguments
|
||||
to use these dm-crypt flags.
|
||||
|
||||
These options are available only for low-level dm-crypt performance tuning,
|
||||
use only if you need a change to default dm-crypt behavior.
|
||||
|
||||
For LUKS2, these flags can be persistently stored in metadata with
|
||||
the --persistent option.
|
||||
|
||||
* Added support panic_on_corruption option for dm-verity devices (kernel 5.9).
|
||||
|
||||
Veritysetup now supports --panic-on-corruption argument that configures
|
||||
the dm-verity device to panics kernel if a corruption is detected.
|
||||
|
||||
This option is intended for specific configurations, do not use it in
|
||||
standard configurations.
|
||||
|
||||
* Support --master-key-file option for online LUKS2 reencryption
|
||||
|
||||
This can be used for reencryption of devices that uses protected key AES cipher
|
||||
on some mainframes crypto accelerators.
|
||||
|
||||
* Always return EEXIST error code if a device already exists.
|
||||
|
||||
Some libcryptsetup functions (activate_by*) now return EEXIST error code,
|
||||
so the caller can distinguish that call fails because some parallel process
|
||||
already activated the device.
|
||||
Previously all fails returned EINVAL (invalid value).
|
||||
|
||||
* Fix a problem in integritysetup if a hash algorithm has dash in the name.
|
||||
|
||||
If users want to use blake2b/blake2s, the kernel algorithm name includes
|
||||
a dash (like "blake2s-256").
|
||||
Theses algorithms can now be used for integritysetup devices.
|
||||
|
||||
* Fix crypto backend to properly handle ECB mode.
|
||||
|
||||
Even though it should never be used, it should still work for testing :)
|
||||
This fixes a bug introduced in cryptsetup version 2.3.2.
|
||||
|
||||
* TrueCrypt/VeraCrypt compatible mode now supports the activation of devices
|
||||
with a larger sector.
|
||||
|
||||
TrueCrypt/VeraCrypt always uses 512-byte sector for encryption, but for devices
|
||||
with a larger native sector, it stores this value in the header.
|
||||
|
||||
This patch allows activation of such devices, basically ignoring
|
||||
the mentioned sector size.
|
||||
|
||||
* LUKS2: Do not create excessively large headers.
|
||||
|
||||
When creating a LUKS2 header with a specified --offset larger than
|
||||
the LUKS2 header size, do not create a larger file than needed.
|
||||
|
||||
* Fix unspecified sector size for BitLocker compatible mode.
|
||||
|
||||
Some BitLocker devices can contain zeroed sector size in the header.
|
||||
In this case, the 512-byte sector should be used.
|
||||
The bug was introduced in version 2.3.3.
|
||||
|
||||
* Fix reading key data size in metadata for BitLocker compatible mode.
|
||||
|
||||
Such devices with an unexpected entry in metadata can now be activated.
|
||||
|
||||
Thanks to all users reporting these problems, BitLocker metadata documentation
|
||||
is not publicly available, and we depend only on these reports.
|
||||
|
||||
* Fix typos in documentation.
|
||||
181
docs/v2.3.5-ReleaseNotes
Normal file
181
docs/v2.3.5-ReleaseNotes
Normal file
@@ -0,0 +1,181 @@
|
||||
Cryptsetup 2.3.5 Release Notes
|
||||
==============================
|
||||
Stable bug-fix release with minor extensions.
|
||||
|
||||
All users of cryptsetup 2.x and later should upgrade to this version.
|
||||
|
||||
Changes since version 2.3.4
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* Fix partial reads of passphrase from an interactive terminal.
|
||||
Some stable kernels (5.3.11) started to return buffer from a terminal
|
||||
in parts of maximal size 64 bytes.
|
||||
This breaks the reading of passphrases longer than 64 characters
|
||||
entered through an interactive terminal. The change is already fixed
|
||||
in later kernel releases, but tools now support such partial read from
|
||||
terminal properly.
|
||||
|
||||
* Fix maximal length of password entered through a terminal.
|
||||
Now the maximal interactive passphrase length is exactly
|
||||
512 characters (not 511).
|
||||
|
||||
* integritysetup: support new dm-integrity HMAC recalculation options.
|
||||
|
||||
In older kernels (since version 4.19), an attacker can force
|
||||
an automatic recalculation of integrity tags by modifying
|
||||
the dm-integrity superblock.
|
||||
This is a problem with a keyed algorithms (HMAC), where it expects
|
||||
nobody can trigger such recalculation without the key.
|
||||
(Automatic recalculation will start after the next activation.)
|
||||
|
||||
Note that dm-integrity in standalone mode was *not* supposed
|
||||
to provide cryptographic data integrity protection.
|
||||
Despite that, we try to keep the system secure if keyed algorithms
|
||||
are used.
|
||||
Thank Daniel Glöckner for the original report of this problem.
|
||||
|
||||
Authenticated encryption that provides data integrity protection (in
|
||||
combination with dm-crypt and LUKS2) is not affected by this problem.
|
||||
|
||||
The fix in the kernel for this problem contains two parts.
|
||||
|
||||
Firstly, the dm-integrity kernel module disables integrity
|
||||
recalculation if keyed algorithms (HMAC) are used.
|
||||
This change is included in long-term stable kernels.
|
||||
|
||||
Secondly, since the kernel version 5.11, dm-integrity introduces
|
||||
modified protection where a journal-integrity algorithm guards
|
||||
superblock; also, journal sections are protected. An attacker cannot
|
||||
copy sectors from one journal section to another, and the superblock
|
||||
also contains salt to prevent header replacement from another device.
|
||||
|
||||
If you want to protect data with HMAC, you should always also use HMAC
|
||||
for --journal-integrity. Keys can be independent.
|
||||
If HMAC is used for data but not for the journal, the recalculation
|
||||
option is disabled.
|
||||
|
||||
If you need to use (insecure) backward compatibility implementation,
|
||||
two new integritysetup options are introduced:
|
||||
- Use --integrity-legacy-recalc (instead of --integrity-recalc)
|
||||
to allow recalculation on legacy devices.
|
||||
- Use --integrity-legacy-hmac in format action to force old insecure
|
||||
HMAC format.
|
||||
|
||||
Libcryptsetup API also introduces flags
|
||||
CRYPT_COMPAT_LEGACY_INTEGRITY_HMAC and
|
||||
CRYPT_COMPAT_LEGACY_INTEGRITY_RECALC
|
||||
to set these through crypt_set_compatibility() call.
|
||||
|
||||
* integritysetup: display of recalculating sector in dump command.
|
||||
|
||||
* veritysetup: fix verity FEC if stored in the same image with hashes.
|
||||
|
||||
Optional FEC (Forward Error Correction) data should cover the whole
|
||||
data area, hashes (Merkle tree), and optionally additional metadata
|
||||
(located after hash area).
|
||||
|
||||
Unfortunately, if FEC data is stored in the same file as hash,
|
||||
the calculation wrongly used the whole file size, thus overlaps with
|
||||
the FEC area itself. This produced unusable and too large FEC data.
|
||||
There is no problem if the FEC image is a separate image.
|
||||
|
||||
The problem is now fixed, introducing FEC blocks calculation as:
|
||||
- If the hash device is in a separate image, metadata covers the
|
||||
whole rest of the image after the hash area. (Unchanged behavior.)
|
||||
- If hash and FEC device is in the image, metadata ends on the FEC
|
||||
area offset.
|
||||
|
||||
Note: there is also a fix for FEC in the dm-verity kernel (on the way
|
||||
to stable kernels) that fixes error correction with larger RS roots.
|
||||
|
||||
* veritysetup: run FEC repair check even if root hash fails.
|
||||
|
||||
Note: The userspace FEC verify command reports are only informational
|
||||
for now. Code does not check verity hash after FEC recovery in
|
||||
userspace. The Reed-Solomon decoder can then report the possibility
|
||||
that it fixed data even if parity is too damaged.
|
||||
This will be fixed in the next major release.
|
||||
|
||||
* veritysetup: do not process hash image if hash area is empty.
|
||||
|
||||
Sometimes the device is so small that there is only a root hash
|
||||
needed, and the hash area is not used.
|
||||
Also, the size of the hash image is not increased for hash block
|
||||
alignment in this case.
|
||||
|
||||
* veritysetup: store verity hash algorithm in superblock in lowercase.
|
||||
|
||||
Otherwise, the kernel could refuse the activation of the device.
|
||||
|
||||
* bitlk: fix a crash if the device disappears during BitLocker scan.
|
||||
|
||||
* bitlk: show a better error when trying to open an NTFS device.
|
||||
|
||||
Both BitLocker version 1 and NTFS have the same signature.
|
||||
If a user opens an NTFS device without BitLocker, it now correctly
|
||||
informs that it is not a BITLK device.
|
||||
|
||||
* bitlk: add support for startup key protected VMKs.
|
||||
|
||||
The startup key can be provided in --key-file option for open command.
|
||||
|
||||
* Fix LUKS1 repair code (regression since version 1.7.x).
|
||||
|
||||
We cannot trust possibly broken keyslots metadata in repair, so the
|
||||
code recalculates them instead.
|
||||
This makes the repair code working again when the master boot record
|
||||
signature overwrites the LUKS header.
|
||||
|
||||
* Fix luksKeyChange for LUKS2 with assigned tokens.
|
||||
|
||||
The token references are now correctly assigned to the new keyslot
|
||||
number.
|
||||
|
||||
* Fix cryptsetup resize using LUKS2 tokens.
|
||||
|
||||
Code needlessly asked for passphrase even though volume key was
|
||||
already unlocked via LUKS2 token.
|
||||
|
||||
* Print a visible error if device resize is not supported.
|
||||
|
||||
* Add error message when suspending wrong non-LUKS device.
|
||||
|
||||
* Fix default XTS mode key size in reencryption.
|
||||
|
||||
The same luksFormat logic (double key size because XTS uses two keys)
|
||||
is applied in the reencryption code.
|
||||
|
||||
* Rephrase missing locking directory warning and move it to debug level.
|
||||
|
||||
The system should later provide a safe transition to tempdir
|
||||
configuration, so creating locking directory inside libcryptsetup
|
||||
call is safe.
|
||||
|
||||
* Many fixes for the use of cipher_null (empty debug cipher).
|
||||
|
||||
Support for this empty cipher was intended as a debug feature and for
|
||||
measuring performance overhead. Unfortunately, many systems started to
|
||||
use it as an "empty shell" for LUKS (to enable encryption later).
|
||||
|
||||
This use is very dangerous and it creates a false sense of security.
|
||||
|
||||
Anyway, to not break such systems, we try to support these
|
||||
configurations.
|
||||
Using cipher_null in any production system is strongly discouraged!
|
||||
|
||||
Fixes include:
|
||||
- allow LUKS resume for a device with cipher_null.
|
||||
- do not upload key in keyring when data cipher is null.
|
||||
- switch to default cipher when reencrypting cipher_null device.
|
||||
- replace possible bogus cipher_null keyslots before reencryption.
|
||||
- fix broken detection of null cipher in LUKS2.
|
||||
cipher_null is no longer possible to be used in keyslot encryption
|
||||
in LUKS2, it can be used only for data for debugging purposes.
|
||||
|
||||
* Fixes for libpasswdqc 2.0.x (optional passphrase quality check).
|
||||
|
||||
* Fixes for problems discovered by various tools for code analysis.
|
||||
|
||||
Fixes include a rework of libpopt command line option string leaks.
|
||||
|
||||
* Various fixes to man pages.
|
||||
@@ -22,7 +22,8 @@ libcryptsetup_la_CPPFLAGS = $(AM_CPPFLAGS) \
|
||||
-I $(top_srcdir)/lib/loopaes \
|
||||
-I $(top_srcdir)/lib/verity \
|
||||
-I $(top_srcdir)/lib/tcrypt \
|
||||
-I $(top_srcdir)/lib/integrity
|
||||
-I $(top_srcdir)/lib/integrity \
|
||||
-I $(top_srcdir)/lib/bitlk
|
||||
|
||||
libcryptsetup_la_DEPENDENCIES = libutils_io.la libcrypto_backend.la lib/libcryptsetup.sym
|
||||
|
||||
@@ -39,6 +40,7 @@ libcryptsetup_la_LIBADD = \
|
||||
@LIBARGON2_LIBS@ \
|
||||
@JSON_C_LIBS@ \
|
||||
@BLKID_LIBS@ \
|
||||
$(LTLIBICONV) \
|
||||
libcrypto_backend.la \
|
||||
libutils_io.la
|
||||
|
||||
@@ -64,6 +66,7 @@ libcryptsetup_la_SOURCES = \
|
||||
lib/utils_device_locking.c \
|
||||
lib/utils_device_locking.h \
|
||||
lib/utils_pbkdf.c \
|
||||
lib/utils_safe_memory.c \
|
||||
lib/utils_storage_wrappers.c \
|
||||
lib/utils_storage_wrappers.h \
|
||||
lib/libdevmapper.c \
|
||||
@@ -74,7 +77,7 @@ libcryptsetup_la_SOURCES = \
|
||||
lib/base64.h \
|
||||
lib/base64.c \
|
||||
lib/integrity/integrity.h \
|
||||
lib/integrity/integrity.c \
|
||||
lib/integrity/integrity.c \
|
||||
lib/loopaes/loopaes.h \
|
||||
lib/loopaes/loopaes.c \
|
||||
lib/tcrypt/tcrypt.h \
|
||||
@@ -90,7 +93,7 @@ libcryptsetup_la_SOURCES = \
|
||||
lib/verity/verity.h \
|
||||
lib/verity/rs_encode_char.c \
|
||||
lib/verity/rs_decode_char.c \
|
||||
lib/verity/rs.h \
|
||||
lib/verity/rs.h \
|
||||
lib/luks2/luks2_disk_metadata.c \
|
||||
lib/luks2/luks2_json_format.c \
|
||||
lib/luks2/luks2_json_metadata.c \
|
||||
@@ -107,4 +110,6 @@ libcryptsetup_la_SOURCES = \
|
||||
lib/luks2/luks2_internal.h \
|
||||
lib/luks2/luks2.h \
|
||||
lib/utils_blkid.c \
|
||||
lib/utils_blkid.h
|
||||
lib/utils_blkid.h \
|
||||
lib/bitlk/bitlk.h \
|
||||
lib/bitlk/bitlk.c
|
||||
|
||||
1382
lib/bitlk/bitlk.c
Normal file
1382
lib/bitlk/bitlk.c
Normal file
File diff suppressed because it is too large
Load Diff
131
lib/bitlk/bitlk.h
Normal file
131
lib/bitlk/bitlk.h
Normal file
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* BITLK (BitLocker-compatible) header definition
|
||||
*
|
||||
* Copyright (C) 2019-2021 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2019-2021 Milan Broz
|
||||
* Copyright (C) 2019-2021 Vojtech Trefny
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This file is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this file; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#ifndef _CRYPTSETUP_BITLK_H
|
||||
#define _CRYPTSETUP_BITLK_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
struct crypt_device;
|
||||
struct device;
|
||||
|
||||
#define BITLK_NONCE_SIZE 12
|
||||
#define BITLK_SALT_SIZE 16
|
||||
#define BITLK_VMK_MAC_TAG_SIZE 16
|
||||
|
||||
#define BITLK_STATE_NORMAL 0x0004
|
||||
|
||||
typedef enum {
|
||||
BITLK_ENCRYPTION_TYPE_NORMAL = 0,
|
||||
BITLK_ENCRYPTION_TYPE_EOW,
|
||||
BITLK_ENCRYPTION_TYPE_UNKNOWN,
|
||||
} BITLKEncryptionType;
|
||||
|
||||
typedef enum {
|
||||
BITLK_PROTECTION_CLEAR_KEY = 0,
|
||||
BITLK_PROTECTION_TPM,
|
||||
BITLK_PROTECTION_STARTUP_KEY,
|
||||
BITLK_PROTECTION_TPM_PIN,
|
||||
BITLK_PROTECTION_RECOVERY_PASSPHRASE,
|
||||
BITLK_PROTECTION_PASSPHRASE,
|
||||
BITLK_PROTECTION_SMART_CARD,
|
||||
BITLK_PROTECTION_UNKNOWN,
|
||||
} BITLKVMKProtection;
|
||||
|
||||
typedef enum {
|
||||
BITLK_ENTRY_TYPE_PROPERTY = 0x0000,
|
||||
BITLK_ENTRY_TYPE_VMK = 0x0002,
|
||||
BITLK_ENTRY_TYPE_FVEK = 0x0003,
|
||||
BITLK_ENTRY_TYPE_STARTUP_KEY = 0x0006,
|
||||
BITLK_ENTRY_TYPE_DESCRIPTION = 0x0007,
|
||||
BITLK_ENTRY_TYPE_VOLUME_HEADER = 0x000f,
|
||||
} BITLKFVEEntryType;
|
||||
|
||||
typedef enum {
|
||||
BITLK_ENTRY_VALUE_ERASED = 0x0000,
|
||||
BITLK_ENTRY_VALUE_KEY = 0x0001,
|
||||
BITLK_ENTRY_VALUE_STRING = 0x0002,
|
||||
BITLK_ENTRY_VALUE_STRETCH_KEY = 0x0003,
|
||||
BITLK_ENTRY_VALUE_USE_KEY = 0x0004,
|
||||
BITLK_ENTRY_VALUE_ENCRYPTED_KEY = 0x0005,
|
||||
BITLK_ENTRY_VALUE_TPM_KEY = 0x0006,
|
||||
BITLK_ENTRY_VALUE_VALIDATION = 0x0007,
|
||||
BITLK_ENTRY_VALUE_VMK = 0x0008,
|
||||
BITLK_ENTRY_VALUE_EXTERNAL_KEY = 0x0009,
|
||||
BITLK_ENTRY_VALUE_OFFSET_SIZE = 0x000f,
|
||||
BITLK_ENTRY_VALUE_RECOVERY_TIME = 0x015,
|
||||
} BITLKFVEEntryValue;
|
||||
|
||||
struct bitlk_vmk {
|
||||
char *guid;
|
||||
char *name;
|
||||
BITLKVMKProtection protection;
|
||||
uint8_t salt[BITLK_SALT_SIZE];
|
||||
uint8_t mac_tag[BITLK_VMK_MAC_TAG_SIZE];
|
||||
uint8_t nonce[BITLK_NONCE_SIZE];
|
||||
struct volume_key *vk;
|
||||
struct bitlk_vmk *next;
|
||||
};
|
||||
|
||||
struct bitlk_fvek {
|
||||
uint8_t mac_tag[BITLK_VMK_MAC_TAG_SIZE];
|
||||
uint8_t nonce[BITLK_NONCE_SIZE];
|
||||
struct volume_key *vk;
|
||||
};
|
||||
|
||||
struct bitlk_metadata {
|
||||
uint16_t sector_size;
|
||||
bool togo;
|
||||
bool state;
|
||||
BITLKEncryptionType type;
|
||||
const char *cipher;
|
||||
const char *cipher_mode;
|
||||
uint16_t key_size;
|
||||
char *guid;
|
||||
uint64_t creation_time;
|
||||
char *description;
|
||||
uint64_t metadata_offset[3];
|
||||
uint32_t metadata_version;
|
||||
uint64_t volume_header_offset;
|
||||
uint64_t volume_header_size;
|
||||
struct bitlk_vmk *vmks;
|
||||
struct bitlk_fvek *fvek;
|
||||
};
|
||||
|
||||
int BITLK_read_sb(struct crypt_device *cd, struct bitlk_metadata *params);
|
||||
|
||||
int BITLK_dump(struct crypt_device *cd, struct device *device, struct bitlk_metadata *params);
|
||||
|
||||
int BITLK_activate(struct crypt_device *cd,
|
||||
const char *name,
|
||||
const char *password,
|
||||
size_t passwordLen,
|
||||
const struct bitlk_metadata *params,
|
||||
uint32_t flags);
|
||||
|
||||
void BITLK_bitlk_fvek_free(struct bitlk_fvek *fvek);
|
||||
void BITLK_bitlk_vmk_free(struct bitlk_vmk *vmk);
|
||||
void BITLK_bitlk_metadata_free(struct bitlk_metadata *params);
|
||||
|
||||
#endif
|
||||
@@ -2,8 +2,8 @@
|
||||
* cryptsetup plain device helper functions
|
||||
*
|
||||
* Copyright (C) 2004 Jana Saout <jana@saout.de>
|
||||
* Copyright (C) 2010-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2019 Milan Broz
|
||||
* Copyright (C) 2010-2021 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2021 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
|
||||
* these licenses can be found at:
|
||||
*
|
||||
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||
* - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* You should have received a copy of both of these licenses along with this
|
||||
* software. If not, they may be obtained at the above URLs.
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
|
||||
* these licenses can be found at:
|
||||
*
|
||||
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||
* - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* You should have received a copy of both of these licenses along with this
|
||||
* software. If not, they may be obtained at the above URLs.
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
|
||||
* these licenses can be found at:
|
||||
*
|
||||
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||
* - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* You should have received a copy of both of these licenses along with this
|
||||
* software. If not, they may be obtained at the above URLs.
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
|
||||
* these licenses can be found at:
|
||||
*
|
||||
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||
* - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* You should have received a copy of both of these licenses along with this
|
||||
* software. If not, they may be obtained at the above URLs.
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
|
||||
* these licenses can be found at:
|
||||
*
|
||||
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||
* - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* You should have received a copy of both of these licenses along with this
|
||||
* software. If not, they may be obtained at the above URLs.
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
|
||||
* these licenses can be found at:
|
||||
*
|
||||
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||
* - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* You should have received a copy of both of these licenses along with this
|
||||
* software. If not, they may be obtained at the above URLs.
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
|
||||
* these licenses can be found at:
|
||||
*
|
||||
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||
* - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* You should have received a copy of both of these licenses along with this
|
||||
* software. If not, they may be obtained at the above URLs.
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
|
||||
* these licenses can be found at:
|
||||
*
|
||||
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||
* - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* You should have received a copy of both of these licenses along with this
|
||||
* software. If not, they may be obtained at the above URLs.
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
|
||||
* these licenses can be found at:
|
||||
*
|
||||
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||
* - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* You should have received a copy of both of these licenses along with this
|
||||
* software. If not, they may be obtained at the above URLs.
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
|
||||
* these licenses can be found at:
|
||||
*
|
||||
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||
* - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* You should have received a copy of both of these licenses along with this
|
||||
* software. If not, they may be obtained at the above URLs.
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
|
||||
* these licenses can be found at:
|
||||
*
|
||||
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||
* - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* You should have received a copy of both of these licenses along with this
|
||||
* software. If not, they may be obtained at the above URLs.
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
|
||||
* these licenses can be found at:
|
||||
*
|
||||
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||
* - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* You should have received a copy of both of these licenses along with this
|
||||
* software. If not, they may be obtained at the above URLs.
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
|
||||
* these licenses can be found at:
|
||||
*
|
||||
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||
* - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* You should have received a copy of both of these licenses along with this
|
||||
* software. If not, they may be obtained at the above URLs.
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
|
||||
* these licenses can be found at:
|
||||
*
|
||||
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||
* - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* You should have received a copy of both of these licenses along with this
|
||||
* software. If not, they may be obtained at the above URLs.
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
|
||||
* these licenses can be found at:
|
||||
*
|
||||
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||
* - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* You should have received a copy of both of these licenses along with this
|
||||
* software. If not, they may be obtained at the above URLs.
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* Argon2 PBKDF2 library wrapper
|
||||
*
|
||||
* Copyright (C) 2016-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2016-2019 Milan Broz
|
||||
* Copyright (C) 2016-2021 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2016-2021 Milan Broz
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* Cipher performance check
|
||||
*
|
||||
* Copyright (C) 2018-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2018-2019 Milan Broz
|
||||
* Copyright (C) 2018-2021 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2018-2021 Milan Broz
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -23,6 +23,10 @@
|
||||
#include <time.h>
|
||||
#include "crypto_backend_internal.h"
|
||||
|
||||
#ifndef CLOCK_MONOTONIC_RAW
|
||||
#define CLOCK_MONOTONIC_RAW CLOCK_MONOTONIC
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This is not simulating storage, so using disk block causes extreme overhead.
|
||||
* Let's use some fixed block size where results are more reliable...
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* Linux kernel cipher generic utilities
|
||||
*
|
||||
* Copyright (C) 2018-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2018-2019 Milan Broz
|
||||
* Copyright (C) 2018-2021 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2018-2021 Milan Broz
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -51,6 +51,7 @@ static const struct cipher_alg cipher_algs[] = {
|
||||
{ "paes", NULL, 16, true }, /* protected AES, s390 wrapped key scheme */
|
||||
{ "xchacha12,aes", "adiantum", 32, false },
|
||||
{ "xchacha20,aes", "adiantum", 32, false },
|
||||
{ "sm4", NULL, 16, false },
|
||||
{ NULL, NULL, 0, false }
|
||||
};
|
||||
|
||||
@@ -72,7 +73,13 @@ int crypt_cipher_ivsize(const char *name, const char *mode)
|
||||
{
|
||||
const struct cipher_alg *ca = _get_alg(name, mode);
|
||||
|
||||
return ca ? ca->blocksize : -EINVAL;
|
||||
if (!ca)
|
||||
return -EINVAL;
|
||||
|
||||
if (mode && !strcasecmp(mode, "ecb"))
|
||||
return 0;
|
||||
|
||||
return ca->blocksize;
|
||||
}
|
||||
|
||||
int crypt_cipher_wrapped_key(const char *name, const char *mode)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* crypto backend implementation
|
||||
*
|
||||
* Copyright (C) 2010-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2019 Milan Broz
|
||||
* Copyright (C) 2010-2021 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2021 Milan Broz
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -26,13 +26,12 @@
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
struct crypt_device;
|
||||
struct crypt_hash;
|
||||
struct crypt_hmac;
|
||||
struct crypt_cipher;
|
||||
struct crypt_storage;
|
||||
|
||||
int crypt_backend_init(struct crypt_device *ctx);
|
||||
int crypt_backend_init(void);
|
||||
void crypt_backend_destroy(void);
|
||||
|
||||
#define CRYPT_BACKEND_KERNEL (1 << 0) /* Crypto uses kernel part, for benchmark */
|
||||
@@ -110,7 +109,7 @@ int crypt_cipher_check_kernel(const char *name, const char *mode,
|
||||
/* Storage encryption wrappers */
|
||||
int crypt_storage_init(struct crypt_storage **ctx, size_t sector_size,
|
||||
const char *cipher, const char *cipher_mode,
|
||||
const void *key, size_t key_length);
|
||||
const void *key, size_t key_length, bool large_iv);
|
||||
void crypt_storage_destroy(struct crypt_storage *ctx);
|
||||
int crypt_storage_decrypt(struct crypt_storage *ctx, uint64_t iv_offset,
|
||||
uint64_t length, char *buffer);
|
||||
@@ -119,6 +118,12 @@ int crypt_storage_encrypt(struct crypt_storage *ctx, uint64_t iv_offset,
|
||||
|
||||
bool crypt_storage_kernel_only(struct crypt_storage *ctx);
|
||||
|
||||
/* Temporary Bitlk helper */
|
||||
int crypt_bitlk_decrypt_key(const void *key, size_t key_length,
|
||||
const char *in, char *out, size_t length,
|
||||
const char *iv, size_t iv_length,
|
||||
const char *tag, size_t tag_length);
|
||||
|
||||
/* Memzero helper (memset on stack can be optimized out) */
|
||||
static inline void crypt_backend_memzero(void *s, size_t n)
|
||||
{
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* crypto backend implementation
|
||||
*
|
||||
* Copyright (C) 2010-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2019 Milan Broz
|
||||
* Copyright (C) 2010-2021 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2021 Milan Broz
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -55,5 +55,9 @@ int crypt_cipher_decrypt_kernel(struct crypt_cipher_kernel *ctx,
|
||||
const char *in, char *out, size_t length,
|
||||
const char *iv, size_t iv_length);
|
||||
void crypt_cipher_destroy_kernel(struct crypt_cipher_kernel *ctx);
|
||||
int crypt_bitlk_decrypt_key_kernel(const void *key, size_t key_length,
|
||||
const char *in, char *out, size_t length,
|
||||
const char *iv, size_t iv_length,
|
||||
const char *tag, size_t tag_length);
|
||||
|
||||
#endif /* _CRYPTO_BACKEND_INTERNAL_H */
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* Linux kernel userspace API crypto backend implementation (skcipher)
|
||||
*
|
||||
* Copyright (C) 2012-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2019 Milan Broz
|
||||
* Copyright (C) 2012-2021 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2021 Milan Broz
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -40,6 +40,10 @@
|
||||
#define SOL_ALG 279
|
||||
#endif
|
||||
|
||||
#ifndef ALG_SET_AEAD_AUTHSIZE
|
||||
#define ALG_SET_AEAD_AUTHSIZE 5
|
||||
#endif
|
||||
|
||||
/*
|
||||
* ciphers
|
||||
*
|
||||
@@ -49,7 +53,7 @@
|
||||
*/
|
||||
static int _crypt_cipher_init(struct crypt_cipher_kernel *ctx,
|
||||
const void *key, size_t key_length,
|
||||
struct sockaddr_alg *sa)
|
||||
size_t tag_length, struct sockaddr_alg *sa)
|
||||
{
|
||||
if (!ctx)
|
||||
return -EINVAL;
|
||||
@@ -71,6 +75,11 @@ static int _crypt_cipher_init(struct crypt_cipher_kernel *ctx,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (tag_length && setsockopt(ctx->tfmfd, SOL_ALG, ALG_SET_AEAD_AUTHSIZE, NULL, tag_length) < 0) {
|
||||
crypt_cipher_destroy_kernel(ctx);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ctx->opfd = accept(ctx->tfmfd, NULL, 0);
|
||||
if (ctx->opfd < 0) {
|
||||
crypt_cipher_destroy_kernel(ctx);
|
||||
@@ -93,12 +102,13 @@ int crypt_cipher_init_kernel(struct crypt_cipher_kernel *ctx, const char *name,
|
||||
|
||||
snprintf((char *)sa.salg_name, sizeof(sa.salg_name), "%s(%s)", mode, name);
|
||||
|
||||
return _crypt_cipher_init(ctx, key, key_length, &sa);
|
||||
return _crypt_cipher_init(ctx, key, key_length, 0, &sa);
|
||||
}
|
||||
|
||||
/* The in/out should be aligned to page boundary */
|
||||
static int _crypt_cipher_crypt(struct crypt_cipher_kernel *ctx,
|
||||
const char *in, char *out, size_t length,
|
||||
const char *in, size_t in_length,
|
||||
char *out, size_t out_length,
|
||||
const char *iv, size_t iv_length,
|
||||
uint32_t direction)
|
||||
{
|
||||
@@ -109,7 +119,7 @@ static int _crypt_cipher_crypt(struct crypt_cipher_kernel *ctx,
|
||||
uint32_t *type;
|
||||
struct iovec iov = {
|
||||
.iov_base = (void*)(uintptr_t)in,
|
||||
.iov_len = length,
|
||||
.iov_len = in_length,
|
||||
};
|
||||
int iv_msg_size = iv ? CMSG_SPACE(sizeof(*alg_iv) + iv_length) : 0;
|
||||
char buffer[CMSG_SPACE(sizeof(*type)) + iv_msg_size];
|
||||
@@ -120,7 +130,7 @@ static int _crypt_cipher_crypt(struct crypt_cipher_kernel *ctx,
|
||||
.msg_iovlen = 1,
|
||||
};
|
||||
|
||||
if (!in || !out || !length)
|
||||
if (!in || !out || !in_length)
|
||||
return -EINVAL;
|
||||
|
||||
if ((!iv && iv_length) || (iv && !iv_length))
|
||||
@@ -142,6 +152,9 @@ static int _crypt_cipher_crypt(struct crypt_cipher_kernel *ctx,
|
||||
/* Set IV */
|
||||
if (iv) {
|
||||
header = CMSG_NXTHDR(&msg, header);
|
||||
if (!header)
|
||||
return -EINVAL;
|
||||
|
||||
header->cmsg_level = SOL_ALG;
|
||||
header->cmsg_type = ALG_SET_IV;
|
||||
header->cmsg_len = iv_msg_size;
|
||||
@@ -151,13 +164,13 @@ static int _crypt_cipher_crypt(struct crypt_cipher_kernel *ctx,
|
||||
}
|
||||
|
||||
len = sendmsg(ctx->opfd, &msg, 0);
|
||||
if (len != (ssize_t)length) {
|
||||
if (len != (ssize_t)(in_length)) {
|
||||
r = -EIO;
|
||||
goto bad;
|
||||
}
|
||||
|
||||
len = read(ctx->opfd, out, length);
|
||||
if (len != (ssize_t)length)
|
||||
len = read(ctx->opfd, out, out_length);
|
||||
if (len != (ssize_t)out_length)
|
||||
r = -EIO;
|
||||
bad:
|
||||
crypt_backend_memzero(buffer, sizeof(buffer));
|
||||
@@ -168,7 +181,7 @@ int crypt_cipher_encrypt_kernel(struct crypt_cipher_kernel *ctx,
|
||||
const char *in, char *out, size_t length,
|
||||
const char *iv, size_t iv_length)
|
||||
{
|
||||
return _crypt_cipher_crypt(ctx, in, out, length,
|
||||
return _crypt_cipher_crypt(ctx, in, length, out, length,
|
||||
iv, iv_length, ALG_OP_ENCRYPT);
|
||||
}
|
||||
|
||||
@@ -176,7 +189,7 @@ int crypt_cipher_decrypt_kernel(struct crypt_cipher_kernel *ctx,
|
||||
const char *in, char *out, size_t length,
|
||||
const char *iv, size_t iv_length)
|
||||
{
|
||||
return _crypt_cipher_crypt(ctx, in, out, length,
|
||||
return _crypt_cipher_crypt(ctx, in, length, out, length,
|
||||
iv, iv_length, ALG_OP_DECRYPT);
|
||||
}
|
||||
|
||||
@@ -243,13 +256,56 @@ int crypt_cipher_check_kernel(const char *name, const char *mode,
|
||||
memset(key, 0xab, key_length);
|
||||
*key = 0xef;
|
||||
|
||||
r = _crypt_cipher_init(&c, key, key_length, &sa);
|
||||
r = _crypt_cipher_init(&c, key, key_length, 0, &sa);
|
||||
crypt_cipher_destroy_kernel(&c);
|
||||
free(key);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int crypt_bitlk_decrypt_key_kernel(const void *key, size_t key_length,
|
||||
const char *in, char *out, size_t length,
|
||||
const char *iv, size_t iv_length,
|
||||
const char *tag, size_t tag_length)
|
||||
{
|
||||
struct crypt_cipher_kernel c;
|
||||
struct sockaddr_alg sa = {
|
||||
.salg_family = AF_ALG,
|
||||
.salg_type = "aead",
|
||||
.salg_name = "ccm(aes)",
|
||||
};
|
||||
int r;
|
||||
char buffer[128], ccm_iv[16];
|
||||
|
||||
if (length + tag_length > sizeof(buffer))
|
||||
return -EINVAL;
|
||||
|
||||
if (iv_length > sizeof(ccm_iv) - 2)
|
||||
return -EINVAL;
|
||||
|
||||
r = _crypt_cipher_init(&c, key, key_length, tag_length, &sa);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
memcpy(buffer, in, length);
|
||||
memcpy(buffer + length, tag, tag_length);
|
||||
|
||||
/* CCM IV - RFC3610 */
|
||||
memset(ccm_iv, 0, sizeof(ccm_iv));
|
||||
ccm_iv[0] = 15 - iv_length - 1;
|
||||
memcpy(ccm_iv + 1, iv, iv_length);
|
||||
memset(ccm_iv + 1 + iv_length, 0, ccm_iv[0] + 1);
|
||||
iv_length = sizeof(ccm_iv);
|
||||
|
||||
r = _crypt_cipher_crypt(&c, buffer, length + tag_length, out, length,
|
||||
ccm_iv, iv_length, ALG_OP_DECRYPT);
|
||||
|
||||
crypt_cipher_destroy_kernel(&c);
|
||||
crypt_backend_memzero(buffer, sizeof(buffer));
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
#else /* ENABLE_AF_ALG */
|
||||
int crypt_cipher_init_kernel(struct crypt_cipher_kernel *ctx, const char *name,
|
||||
const char *mode, const void *key, size_t key_length)
|
||||
@@ -280,4 +336,11 @@ int crypt_cipher_check_kernel(const char *name, const char *mode,
|
||||
/* Cannot check, expect success. */
|
||||
return 0;
|
||||
}
|
||||
int crypt_bitlk_decrypt_key_kernel(const void *key, size_t key_length,
|
||||
const char *in, char *out, size_t length,
|
||||
const char *iv, size_t iv_length,
|
||||
const char *tag, size_t tag_length)
|
||||
{
|
||||
return -ENOTSUP;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* GCRYPT crypto backend implementation
|
||||
*
|
||||
* Copyright (C) 2010-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2019 Milan Broz
|
||||
* Copyright (C) 2010-2021 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2021 Milan Broz
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -53,7 +53,7 @@ struct crypt_cipher {
|
||||
|
||||
/*
|
||||
* Test for wrong Whirlpool variant,
|
||||
* Ref: http://lists.gnupg.org/pipermail/gcrypt-devel/2014-January/002889.html
|
||||
* Ref: https://lists.gnupg.org/pipermail/gcrypt-devel/2014-January/002889.html
|
||||
*/
|
||||
static void crypt_hash_test_whirlpool_bug(void)
|
||||
{
|
||||
@@ -89,7 +89,7 @@ static void crypt_hash_test_whirlpool_bug(void)
|
||||
crypto_backend_whirlpool_bug = 1;
|
||||
}
|
||||
|
||||
int crypt_backend_init(struct crypt_device *ctx)
|
||||
int crypt_backend_init(void)
|
||||
{
|
||||
if (crypto_backend_initialised)
|
||||
return 0;
|
||||
@@ -479,3 +479,43 @@ bool crypt_cipher_kernel_only(struct crypt_cipher *ctx)
|
||||
{
|
||||
return ctx->use_kernel;
|
||||
}
|
||||
|
||||
int crypt_bitlk_decrypt_key(const void *key, size_t key_length,
|
||||
const char *in, char *out, size_t length,
|
||||
const char *iv, size_t iv_length,
|
||||
const char *tag, size_t tag_length)
|
||||
{
|
||||
#ifdef GCRY_CCM_BLOCK_LEN
|
||||
gcry_cipher_hd_t hd;
|
||||
uint64_t l[3];
|
||||
int r = -EINVAL;
|
||||
|
||||
if (gcry_cipher_open(&hd, GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CCM, 0))
|
||||
return -EINVAL;
|
||||
|
||||
if (gcry_cipher_setkey(hd, key, key_length))
|
||||
goto out;
|
||||
|
||||
if (gcry_cipher_setiv(hd, iv, iv_length))
|
||||
goto out;
|
||||
|
||||
l[0] = length;
|
||||
l[1] = 0;
|
||||
l[2] = tag_length;
|
||||
if (gcry_cipher_ctl(hd, GCRYCTL_SET_CCM_LENGTHS, l, sizeof(l)))
|
||||
goto out;
|
||||
|
||||
if (gcry_cipher_decrypt(hd, out, length, in, length))
|
||||
goto out;
|
||||
|
||||
if (gcry_cipher_checktag(hd, tag, tag_length))
|
||||
goto out;
|
||||
|
||||
r = 0;
|
||||
out:
|
||||
gcry_cipher_close(hd);
|
||||
return r;
|
||||
#else
|
||||
return -ENOTSUP;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* Linux kernel userspace API crypto backend implementation
|
||||
*
|
||||
* Copyright (C) 2010-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2019 Milan Broz
|
||||
* Copyright (C) 2010-2021 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2021 Milan Broz
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -110,7 +110,7 @@ static int crypt_kernel_socket_init(struct sockaddr_alg *sa, int *tfmfd, int *op
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypt_backend_init(struct crypt_device *ctx)
|
||||
int crypt_backend_init(void)
|
||||
{
|
||||
struct utsname uts;
|
||||
struct sockaddr_alg sa = {
|
||||
@@ -392,3 +392,12 @@ bool crypt_cipher_kernel_only(struct crypt_cipher *ctx)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
int crypt_bitlk_decrypt_key(const void *key, size_t key_length,
|
||||
const char *in, char *out, size_t length,
|
||||
const char *iv, size_t iv_length,
|
||||
const char *tag, size_t tag_length)
|
||||
{
|
||||
return crypt_bitlk_decrypt_key_kernel(key, key_length, in, out, length,
|
||||
iv, iv_length, tag, tag_length);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* Nettle crypto backend implementation
|
||||
*
|
||||
* Copyright (C) 2011-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2011-2019 Milan Broz
|
||||
* Copyright (C) 2011-2021 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2011-2021 Milan Broz
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -213,7 +213,7 @@ static struct hash_alg *_get_alg(const char *name)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int crypt_backend_init(struct crypt_device *ctx)
|
||||
int crypt_backend_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -433,3 +433,12 @@ bool crypt_cipher_kernel_only(struct crypt_cipher *ctx)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
int crypt_bitlk_decrypt_key(const void *key, size_t key_length,
|
||||
const char *in, char *out, size_t length,
|
||||
const char *iv, size_t iv_length,
|
||||
const char *tag, size_t tag_length)
|
||||
{
|
||||
return crypt_bitlk_decrypt_key_kernel(key, key_length, in, out, length,
|
||||
iv, iv_length, tag, tag_length);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* NSS crypto backend implementation
|
||||
*
|
||||
* Copyright (C) 2010-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2019 Milan Broz
|
||||
* Copyright (C) 2010-2021 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2021 Milan Broz
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -75,7 +75,7 @@ static struct hash_alg *_get_alg(const char *name)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int crypt_backend_init(struct crypt_device *ctx)
|
||||
int crypt_backend_init(void)
|
||||
{
|
||||
if (crypto_backend_initialised)
|
||||
return 0;
|
||||
@@ -381,3 +381,12 @@ bool crypt_cipher_kernel_only(struct crypt_cipher *ctx)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
int crypt_bitlk_decrypt_key(const void *key, size_t key_length,
|
||||
const char *in, char *out, size_t length,
|
||||
const char *iv, size_t iv_length,
|
||||
const char *tag, size_t tag_length)
|
||||
{
|
||||
return crypt_bitlk_decrypt_key_kernel(key, key_length, in, out, length,
|
||||
iv, iv_length, tag, tag_length);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* OPENSSL crypto backend implementation
|
||||
*
|
||||
* Copyright (C) 2010-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2019 Milan Broz
|
||||
* Copyright (C) 2010-2021 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2021 Milan Broz
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -35,6 +35,8 @@
|
||||
#include <openssl/rand.h>
|
||||
#include "crypto_backend_internal.h"
|
||||
|
||||
#define CONST_CAST(x) (x)(uintptr_t)
|
||||
|
||||
static int crypto_backend_initialised = 0;
|
||||
|
||||
struct crypt_hash {
|
||||
@@ -119,7 +121,7 @@ static const char *openssl_backend_version(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
int crypt_backend_init(struct crypt_device *ctx)
|
||||
int crypt_backend_init(void)
|
||||
{
|
||||
if (crypto_backend_initialised)
|
||||
return 0;
|
||||
@@ -505,3 +507,40 @@ bool crypt_cipher_kernel_only(struct crypt_cipher *ctx)
|
||||
{
|
||||
return ctx->use_kernel;
|
||||
}
|
||||
|
||||
int crypt_bitlk_decrypt_key(const void *key, size_t key_length,
|
||||
const char *in, char *out, size_t length,
|
||||
const char *iv, size_t iv_length,
|
||||
const char *tag, size_t tag_length)
|
||||
{
|
||||
#ifdef EVP_CTRL_CCM_SET_IVLEN
|
||||
EVP_CIPHER_CTX *ctx;
|
||||
int len = 0, r = -EINVAL;
|
||||
|
||||
ctx = EVP_CIPHER_CTX_new();
|
||||
if (!ctx)
|
||||
return -EINVAL;
|
||||
|
||||
if (EVP_DecryptInit_ex(ctx, EVP_aes_256_ccm(), NULL, NULL, NULL) != 1)
|
||||
goto out;
|
||||
|
||||
//EVP_CIPHER_CTX_key_length(ctx)
|
||||
//EVP_CIPHER_CTX_iv_length(ctx)
|
||||
|
||||
if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_IVLEN, iv_length, NULL) != 1)
|
||||
goto out;
|
||||
if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_TAG, tag_length, CONST_CAST(void*)tag) != 1)
|
||||
goto out;
|
||||
|
||||
if (EVP_DecryptInit_ex(ctx, NULL, NULL, key, (const unsigned char*)iv) != 1)
|
||||
goto out;
|
||||
|
||||
if (EVP_DecryptUpdate(ctx, (unsigned char*)out, &len, (const unsigned char*)in, length) == 1)
|
||||
r = 0;
|
||||
out:
|
||||
EVP_CIPHER_CTX_free(ctx);
|
||||
return r;
|
||||
#else
|
||||
return -ENOTSUP;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Generic wrapper for storage encryption modes and Initial Vectors
|
||||
* (reimplementation of some functions from Linux dm-crypt kernel)
|
||||
*
|
||||
* Copyright (C) 2014-2019 Milan Broz
|
||||
* Copyright (C) 2014-2021 Milan Broz
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -31,16 +31,16 @@
|
||||
* IV documentation: https://gitlab.com/cryptsetup/cryptsetup/wikis/DMCrypt
|
||||
*/
|
||||
struct crypt_sector_iv {
|
||||
enum { IV_NONE, IV_NULL, IV_PLAIN, IV_PLAIN64, IV_ESSIV, IV_BENBI, IV_PLAIN64BE } type;
|
||||
enum { IV_NONE, IV_NULL, IV_PLAIN, IV_PLAIN64, IV_ESSIV, IV_BENBI, IV_PLAIN64BE, IV_EBOIV } type;
|
||||
int iv_size;
|
||||
char *iv;
|
||||
struct crypt_cipher *essiv_cipher;
|
||||
int benbi_shift;
|
||||
struct crypt_cipher *cipher;
|
||||
int shift;
|
||||
};
|
||||
|
||||
/* Block encryption storage context */
|
||||
struct crypt_storage {
|
||||
unsigned sector_shift;
|
||||
size_t sector_size;
|
||||
unsigned iv_shift;
|
||||
struct crypt_cipher *cipher;
|
||||
struct crypt_sector_iv cipher_iv;
|
||||
@@ -56,12 +56,15 @@ static int int_log2(unsigned int x)
|
||||
|
||||
static int crypt_sector_iv_init(struct crypt_sector_iv *ctx,
|
||||
const char *cipher_name, const char *mode_name,
|
||||
const char *iv_name, const void *key, size_t key_length)
|
||||
const char *iv_name, const void *key, size_t key_length,
|
||||
size_t sector_size)
|
||||
{
|
||||
int r;
|
||||
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
|
||||
ctx->iv_size = crypt_cipher_ivsize(cipher_name, mode_name);
|
||||
if (ctx->iv_size < 8)
|
||||
if (ctx->iv_size < 0 || (strcmp(mode_name, "ecb") && ctx->iv_size < 8))
|
||||
return -ENOENT;
|
||||
|
||||
if (!strcmp(cipher_name, "cipher_null") ||
|
||||
@@ -86,7 +89,6 @@ static int crypt_sector_iv_init(struct crypt_sector_iv *ctx,
|
||||
char *hash_name = strchr(iv_name, ':');
|
||||
int hash_size;
|
||||
char tmp[256];
|
||||
int r;
|
||||
|
||||
if (!hash_name)
|
||||
return -EINVAL;
|
||||
@@ -114,7 +116,7 @@ static int crypt_sector_iv_init(struct crypt_sector_iv *ctx,
|
||||
return r;
|
||||
}
|
||||
|
||||
r = crypt_cipher_init(&ctx->essiv_cipher, cipher_name, "ecb",
|
||||
r = crypt_cipher_init(&ctx->cipher, cipher_name, "ecb",
|
||||
tmp, hash_size);
|
||||
crypt_backend_memzero(tmp, sizeof(tmp));
|
||||
if (r)
|
||||
@@ -127,7 +129,15 @@ static int crypt_sector_iv_init(struct crypt_sector_iv *ctx,
|
||||
return -EINVAL;
|
||||
|
||||
ctx->type = IV_BENBI;
|
||||
ctx->benbi_shift = SECTOR_SHIFT - log;
|
||||
ctx->shift = SECTOR_SHIFT - log;
|
||||
} else if (!strncasecmp(iv_name, "eboiv", 5)) {
|
||||
r = crypt_cipher_init(&ctx->cipher, cipher_name, "ecb",
|
||||
key, key_length);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
ctx->type = IV_EBOIV;
|
||||
ctx->shift = int_log2(sector_size);
|
||||
} else
|
||||
return -ENOENT;
|
||||
|
||||
@@ -163,14 +173,20 @@ static int crypt_sector_iv_generate(struct crypt_sector_iv *ctx, uint64_t sector
|
||||
case IV_ESSIV:
|
||||
memset(ctx->iv, 0, ctx->iv_size);
|
||||
*(uint64_t *)ctx->iv = cpu_to_le64(sector);
|
||||
return crypt_cipher_encrypt(ctx->essiv_cipher,
|
||||
return crypt_cipher_encrypt(ctx->cipher,
|
||||
ctx->iv, ctx->iv, ctx->iv_size, NULL, 0);
|
||||
break;
|
||||
case IV_BENBI:
|
||||
memset(ctx->iv, 0, ctx->iv_size);
|
||||
val = cpu_to_be64((sector << ctx->benbi_shift) + 1);
|
||||
val = cpu_to_be64((sector << ctx->shift) + 1);
|
||||
memcpy(ctx->iv + ctx->iv_size - sizeof(val), &val, sizeof(val));
|
||||
break;
|
||||
case IV_EBOIV:
|
||||
memset(ctx->iv, 0, ctx->iv_size);
|
||||
*(uint64_t *)ctx->iv = cpu_to_le64(sector << ctx->shift);
|
||||
return crypt_cipher_encrypt(ctx->cipher,
|
||||
ctx->iv, ctx->iv, ctx->iv_size, NULL, 0);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -180,8 +196,8 @@ static int crypt_sector_iv_generate(struct crypt_sector_iv *ctx, uint64_t sector
|
||||
|
||||
static void crypt_sector_iv_destroy(struct crypt_sector_iv *ctx)
|
||||
{
|
||||
if (ctx->type == IV_ESSIV)
|
||||
crypt_cipher_destroy(ctx->essiv_cipher);
|
||||
if (ctx->type == IV_ESSIV || ctx->type == IV_EBOIV)
|
||||
crypt_cipher_destroy(ctx->cipher);
|
||||
|
||||
if (ctx->iv) {
|
||||
memset(ctx->iv, 0, ctx->iv_size);
|
||||
@@ -197,7 +213,8 @@ int crypt_storage_init(struct crypt_storage **ctx,
|
||||
size_t sector_size,
|
||||
const char *cipher,
|
||||
const char *cipher_mode,
|
||||
const void *key, size_t key_length)
|
||||
const void *key, size_t key_length,
|
||||
bool large_iv)
|
||||
{
|
||||
struct crypt_storage *s;
|
||||
char mode_name[64];
|
||||
@@ -229,14 +246,14 @@ int crypt_storage_init(struct crypt_storage **ctx,
|
||||
return r;
|
||||
}
|
||||
|
||||
r = crypt_sector_iv_init(&s->cipher_iv, cipher, mode_name, cipher_iv, key, key_length);
|
||||
r = crypt_sector_iv_init(&s->cipher_iv, cipher, mode_name, cipher_iv, key, key_length, sector_size);
|
||||
if (r) {
|
||||
crypt_storage_destroy(s);
|
||||
return r;
|
||||
}
|
||||
|
||||
s->sector_shift = int_log2(sector_size);
|
||||
s->iv_shift = s->sector_shift - SECTOR_SHIFT;
|
||||
s->sector_size = sector_size;
|
||||
s->iv_shift = large_iv ? int_log2(sector_size) - SECTOR_SHIFT : 0;
|
||||
|
||||
*ctx = s;
|
||||
return 0;
|
||||
@@ -249,19 +266,20 @@ int crypt_storage_decrypt(struct crypt_storage *ctx,
|
||||
uint64_t i;
|
||||
int r = 0;
|
||||
|
||||
if (length & ((1 << ctx->sector_shift) - 1))
|
||||
if (length & (ctx->sector_size - 1))
|
||||
return -EINVAL;
|
||||
|
||||
length >>= ctx->sector_shift;
|
||||
if (iv_offset & ((ctx->sector_size >> SECTOR_SHIFT) - 1))
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < length; i++) {
|
||||
r = crypt_sector_iv_generate(&ctx->cipher_iv, iv_offset + (uint64_t)(i << ctx->iv_shift));
|
||||
for (i = 0; i < length; i += ctx->sector_size) {
|
||||
r = crypt_sector_iv_generate(&ctx->cipher_iv, (iv_offset + (i >> SECTOR_SHIFT)) >> ctx->iv_shift);
|
||||
if (r)
|
||||
break;
|
||||
r = crypt_cipher_decrypt(ctx->cipher,
|
||||
&buffer[i << ctx->sector_shift],
|
||||
&buffer[i << ctx->sector_shift],
|
||||
1 << ctx->sector_shift,
|
||||
&buffer[i],
|
||||
&buffer[i],
|
||||
ctx->sector_size,
|
||||
ctx->cipher_iv.iv,
|
||||
ctx->cipher_iv.iv_size);
|
||||
if (r)
|
||||
@@ -278,19 +296,20 @@ int crypt_storage_encrypt(struct crypt_storage *ctx,
|
||||
uint64_t i;
|
||||
int r = 0;
|
||||
|
||||
if (length & ((1 << ctx->sector_shift) - 1))
|
||||
if (length & (ctx->sector_size - 1))
|
||||
return -EINVAL;
|
||||
|
||||
length >>= ctx->sector_shift;
|
||||
if (iv_offset & ((ctx->sector_size >> SECTOR_SHIFT) - 1))
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < length; i++) {
|
||||
r = crypt_sector_iv_generate(&ctx->cipher_iv, iv_offset + (i << ctx->iv_shift));
|
||||
for (i = 0; i < length; i += ctx->sector_size) {
|
||||
r = crypt_sector_iv_generate(&ctx->cipher_iv, (iv_offset + (i >> SECTOR_SHIFT)) >> ctx->iv_shift);
|
||||
if (r)
|
||||
break;
|
||||
r = crypt_cipher_encrypt(ctx->cipher,
|
||||
&buffer[i << ctx->sector_shift],
|
||||
&buffer[i << ctx->sector_shift],
|
||||
1 << ctx->sector_shift,
|
||||
&buffer[i],
|
||||
&buffer[i],
|
||||
ctx->sector_size,
|
||||
ctx->cipher_iv.iv,
|
||||
ctx->cipher_iv.iv_size);
|
||||
if (r)
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
* Copyright (C) 2004 Free Software Foundation
|
||||
*
|
||||
* cryptsetup related changes
|
||||
* Copyright (C) 2012-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2019 Milan Broz
|
||||
* Copyright (C) 2012-2021 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2021 Milan Broz
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* PBKDF performance check
|
||||
* Copyright (C) 2012-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2019 Milan Broz
|
||||
* Copyright (C) 2016-2019 Ondrej Mosnacek
|
||||
* Copyright (C) 2012-2021 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2021 Milan Broz
|
||||
* Copyright (C) 2016-2020 Ondrej Mosnacek
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -27,6 +27,10 @@
|
||||
#include <sys/resource.h>
|
||||
#include "crypto_backend.h"
|
||||
|
||||
#ifndef CLOCK_MONOTONIC_RAW
|
||||
#define CLOCK_MONOTONIC_RAW CLOCK_MONOTONIC
|
||||
#endif
|
||||
|
||||
#define BENCH_MIN_MS 250
|
||||
#define BENCH_MIN_MS_FAST 10
|
||||
#define BENCH_PERCENT_ATLEAST 95
|
||||
@@ -357,8 +361,10 @@ static int crypt_pbkdf_check(const char *kdf, const char *hash,
|
||||
ms = time_ms(&rstart, &rend);
|
||||
if (ms) {
|
||||
PBKDF2_temp = (double)iterations * target_ms / ms;
|
||||
if (PBKDF2_temp > UINT32_MAX)
|
||||
return -EINVAL;
|
||||
if (PBKDF2_temp > UINT32_MAX) {
|
||||
r = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
*iter_secs = (uint32_t)PBKDF2_temp;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Integrity volume handling
|
||||
*
|
||||
* Copyright (C) 2016-2019 Milan Broz
|
||||
* Copyright (C) 2016-2021 Milan Broz
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -22,7 +22,6 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <uuid/uuid.h>
|
||||
|
||||
#include "integrity.h"
|
||||
@@ -41,8 +40,7 @@ static int INTEGRITY_read_superblock(struct crypt_device *cd,
|
||||
if (read_lseek_blockwise(devfd, device_block_size(cd, device),
|
||||
device_alignment(device), sb, sizeof(*sb), offset) != sizeof(*sb) ||
|
||||
memcmp(sb->magic, SB_MAGIC, sizeof(sb->magic)) ||
|
||||
(sb->version != SB_VERSION_1 && sb->version != SB_VERSION_2 &&
|
||||
sb->version != SB_VERSION_3)) {
|
||||
sb->version < SB_VERSION_1 || sb->version > SB_VERSION_5) {
|
||||
log_std(cd, "No integrity superblock detected on %s.\n",
|
||||
device_path(device));
|
||||
r = -EINVAL;
|
||||
@@ -58,7 +56,9 @@ static int INTEGRITY_read_superblock(struct crypt_device *cd,
|
||||
return r;
|
||||
}
|
||||
|
||||
int INTEGRITY_read_sb(struct crypt_device *cd, struct crypt_params_integrity *params)
|
||||
int INTEGRITY_read_sb(struct crypt_device *cd,
|
||||
struct crypt_params_integrity *params,
|
||||
uint32_t *flags)
|
||||
{
|
||||
struct superblock sb;
|
||||
int r;
|
||||
@@ -70,6 +70,9 @@ int INTEGRITY_read_sb(struct crypt_device *cd, struct crypt_params_integrity *pa
|
||||
params->sector_size = SECTOR_SIZE << sb.log2_sectors_per_block;
|
||||
params->tag_size = sb.integrity_tag_size;
|
||||
|
||||
if (flags)
|
||||
*flags = sb.flags;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -89,13 +92,15 @@ int INTEGRITY_dump(struct crypt_device *cd, struct device *device, uint64_t offs
|
||||
log_std(cd, "journal_sections %u\n", sb.journal_sections);
|
||||
log_std(cd, "provided_data_sectors %" PRIu64 "\n", sb.provided_data_sectors);
|
||||
log_std(cd, "sector_size %u\n", SECTOR_SIZE << sb.log2_sectors_per_block);
|
||||
if (sb.version == SB_VERSION_2 && (sb.flags & SB_FLAG_RECALCULATING))
|
||||
if (sb.version >= SB_VERSION_2 && (sb.flags & SB_FLAG_RECALCULATING))
|
||||
log_std(cd, "recalc_sector %" PRIu64 "\n", sb.recalc_sector);
|
||||
log_std(cd, "log2_blocks_per_bitmap %u\n", sb.log2_blocks_per_bitmap_bit);
|
||||
log_std(cd, "flags %s%s%s\n",
|
||||
log_std(cd, "flags %s%s%s%s%s\n",
|
||||
sb.flags & SB_FLAG_HAVE_JOURNAL_MAC ? "have_journal_mac " : "",
|
||||
sb.flags & SB_FLAG_RECALCULATING ? "recalculating " : "",
|
||||
sb.flags & SB_FLAG_DIRTY_BITMAP ? "dirty_bitmap " : "");
|
||||
sb.flags & SB_FLAG_DIRTY_BITMAP ? "dirty_bitmap " : "",
|
||||
sb.flags & SB_FLAG_FIXED_PADDING ? "fix_padding " : "",
|
||||
sb.flags & SB_FLAG_FIXED_HMAC ? "fix_hmac " : "");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -137,6 +142,27 @@ int INTEGRITY_key_size(struct crypt_device *cd, const char *integrity)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Return hash or hmac(hash) size, if known */
|
||||
int INTEGRITY_hash_tag_size(const char *integrity)
|
||||
{
|
||||
char hash[MAX_CIPHER_LEN];
|
||||
int r;
|
||||
|
||||
if (!integrity)
|
||||
return 0;
|
||||
|
||||
if (!strcmp(integrity, "crc32") || !strcmp(integrity, "crc32c"))
|
||||
return 4;
|
||||
|
||||
r = sscanf(integrity, "hmac(%" MAX_CIPHER_LEN_STR "[^)]s", hash);
|
||||
if (r == 1)
|
||||
r = crypt_hash_size(hash);
|
||||
else
|
||||
r = crypt_hash_size(integrity);
|
||||
|
||||
return r < 0 ? 0 : r;
|
||||
}
|
||||
|
||||
int INTEGRITY_tag_size(struct crypt_device *cd,
|
||||
const char *integrity,
|
||||
const char *cipher,
|
||||
@@ -187,7 +213,7 @@ int INTEGRITY_create_dmd_device(struct crypt_device *cd,
|
||||
struct volume_key *journal_crypt_key,
|
||||
struct volume_key *journal_mac_key,
|
||||
struct crypt_dm_active_device *dmd,
|
||||
uint32_t flags)
|
||||
uint32_t flags, uint32_t sb_flags)
|
||||
{
|
||||
int r;
|
||||
|
||||
@@ -198,12 +224,16 @@ int INTEGRITY_create_dmd_device(struct crypt_device *cd,
|
||||
.flags = flags,
|
||||
};
|
||||
|
||||
/* Workaround for kernel dm-integrity table bug */
|
||||
if (sb_flags & SB_FLAG_RECALCULATING)
|
||||
dmd->flags |= CRYPT_ACTIVATE_RECALCULATE;
|
||||
|
||||
r = INTEGRITY_data_sectors(cd, crypt_metadata_device(cd),
|
||||
crypt_get_data_offset(cd) * SECTOR_SIZE, &dmd->size);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return dm_integrity_target_set(&dmd->segment, 0, dmd->size,
|
||||
return dm_integrity_target_set(cd, &dmd->segment, 0, dmd->size,
|
||||
crypt_metadata_device(cd), crypt_data_device(cd),
|
||||
crypt_get_integrity_tag_size(cd), crypt_get_data_offset(cd),
|
||||
crypt_get_sector_size(cd), vk, journal_crypt_key,
|
||||
@@ -213,7 +243,8 @@ int INTEGRITY_create_dmd_device(struct crypt_device *cd,
|
||||
int INTEGRITY_activate_dmd_device(struct crypt_device *cd,
|
||||
const char *name,
|
||||
const char *type,
|
||||
struct crypt_dm_active_device *dmd)
|
||||
struct crypt_dm_active_device *dmd,
|
||||
uint32_t sb_flags)
|
||||
{
|
||||
int r;
|
||||
uint32_t dmi_flags;
|
||||
@@ -238,7 +269,22 @@ int INTEGRITY_activate_dmd_device(struct crypt_device *cd,
|
||||
|
||||
r = dm_create_device(cd, name, type, dmd);
|
||||
if (r < 0 && (dm_flags(cd, DM_INTEGRITY, &dmi_flags) || !(dmi_flags & DM_INTEGRITY_SUPPORTED))) {
|
||||
log_err(cd, _("Kernel doesn't support dm-integrity mapping."));
|
||||
log_err(cd, _("Kernel does not support dm-integrity mapping."));
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
if (r < 0 && (sb_flags & SB_FLAG_FIXED_PADDING) && !dm_flags(cd, DM_INTEGRITY, &dmi_flags) &&
|
||||
!(dmi_flags & DM_INTEGRITY_FIX_PADDING_SUPPORTED)) {
|
||||
log_err(cd, _("Kernel does not support dm-integrity fixed metadata alignment."));
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
if (r < 0 && (dmd->flags & CRYPT_ACTIVATE_RECALCULATE) &&
|
||||
!(crypt_get_compatibility(cd) & CRYPT_COMPAT_LEGACY_INTEGRITY_RECALC) &&
|
||||
((sb_flags & SB_FLAG_FIXED_HMAC) ?
|
||||
(tgt->u.integrity.vk && !tgt->u.integrity.journal_integrity_key) :
|
||||
(tgt->u.integrity.vk || tgt->u.integrity.journal_integrity_key))) {
|
||||
log_err(cd, _("Kernel refuses to activate insecure recalculate option (see legacy activation options to override)."));
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
@@ -251,15 +297,16 @@ int INTEGRITY_activate(struct crypt_device *cd,
|
||||
struct volume_key *vk,
|
||||
struct volume_key *journal_crypt_key,
|
||||
struct volume_key *journal_mac_key,
|
||||
uint32_t flags)
|
||||
uint32_t flags, uint32_t sb_flags)
|
||||
{
|
||||
struct crypt_dm_active_device dmd = {};
|
||||
int r = INTEGRITY_create_dmd_device(cd, params, vk, journal_crypt_key, journal_mac_key, &dmd, flags);
|
||||
int r = INTEGRITY_create_dmd_device(cd, params, vk, journal_crypt_key,
|
||||
journal_mac_key, &dmd, flags, sb_flags);
|
||||
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = INTEGRITY_activate_dmd_device(cd, name, CRYPT_INTEGRITY, &dmd);
|
||||
r = INTEGRITY_activate_dmd_device(cd, name, CRYPT_INTEGRITY, &dmd, sb_flags);
|
||||
dm_targets_free(cd, &dmd);
|
||||
return r;
|
||||
}
|
||||
@@ -289,7 +336,7 @@ int INTEGRITY_format(struct crypt_device *cd,
|
||||
if (params && params->integrity_key_size)
|
||||
vk = crypt_alloc_volume_key(params->integrity_key_size, NULL);
|
||||
|
||||
r = dm_integrity_target_set(tgt, 0, dmdi.size, crypt_metadata_device(cd),
|
||||
r = dm_integrity_target_set(cd, tgt, 0, dmdi.size, crypt_metadata_device(cd),
|
||||
crypt_data_device(cd), crypt_get_integrity_tag_size(cd),
|
||||
crypt_get_data_offset(cd), crypt_get_sector_size(cd), vk,
|
||||
journal_crypt_key, journal_mac_key, params);
|
||||
@@ -303,7 +350,7 @@ int INTEGRITY_format(struct crypt_device *cd,
|
||||
|
||||
r = device_block_adjust(cd, tgt->data_device, DEV_EXCL, tgt->u.integrity.offset, NULL, NULL);
|
||||
if (r < 0 && (dm_flags(cd, DM_INTEGRITY, &dmi_flags) || !(dmi_flags & DM_INTEGRITY_SUPPORTED))) {
|
||||
log_err(cd, _("Kernel doesn't support dm-integrity mapping."));
|
||||
log_err(cd, _("Kernel does not support dm-integrity mapping."));
|
||||
r = -ENOTSUP;
|
||||
}
|
||||
if (r) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Integrity header definition
|
||||
*
|
||||
* Copyright (C) 2016-2019 Milan Broz
|
||||
* Copyright (C) 2016-2021 Milan Broz
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -34,10 +34,14 @@ struct crypt_dm_active_device;
|
||||
#define SB_VERSION_1 1
|
||||
#define SB_VERSION_2 2
|
||||
#define SB_VERSION_3 3
|
||||
#define SB_VERSION_4 4
|
||||
#define SB_VERSION_5 5
|
||||
|
||||
#define SB_FLAG_HAVE_JOURNAL_MAC (1 << 0)
|
||||
#define SB_FLAG_RECALCULATING (1 << 1) /* V2 only */
|
||||
#define SB_FLAG_DIRTY_BITMAP (1 << 2) /* V3 only */
|
||||
#define SB_FLAG_FIXED_PADDING (1 << 3) /* V4 only */
|
||||
#define SB_FLAG_FIXED_HMAC (1 << 4) /* V5 only */
|
||||
|
||||
struct superblock {
|
||||
uint8_t magic[8];
|
||||
@@ -53,7 +57,9 @@ struct superblock {
|
||||
uint64_t recalc_sector; /* V2 only */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
int INTEGRITY_read_sb(struct crypt_device *cd, struct crypt_params_integrity *params);
|
||||
int INTEGRITY_read_sb(struct crypt_device *cd,
|
||||
struct crypt_params_integrity *params,
|
||||
uint32_t *flags);
|
||||
|
||||
int INTEGRITY_dump(struct crypt_device *cd, struct device *device, uint64_t offset);
|
||||
|
||||
@@ -66,6 +72,7 @@ int INTEGRITY_tag_size(struct crypt_device *cd,
|
||||
const char *integrity,
|
||||
const char *cipher,
|
||||
const char *cipher_mode);
|
||||
int INTEGRITY_hash_tag_size(const char *integrity);
|
||||
|
||||
int INTEGRITY_format(struct crypt_device *cd,
|
||||
const struct crypt_params_integrity *params,
|
||||
@@ -78,7 +85,7 @@ int INTEGRITY_activate(struct crypt_device *cd,
|
||||
struct volume_key *vk,
|
||||
struct volume_key *journal_crypt_key,
|
||||
struct volume_key *journal_mac_key,
|
||||
uint32_t flags);
|
||||
uint32_t flags, uint32_t sb_flags);
|
||||
|
||||
int INTEGRITY_create_dmd_device(struct crypt_device *cd,
|
||||
const struct crypt_params_integrity *params,
|
||||
@@ -86,10 +93,11 @@ int INTEGRITY_create_dmd_device(struct crypt_device *cd,
|
||||
struct volume_key *journal_crypt_key,
|
||||
struct volume_key *journal_mac_key,
|
||||
struct crypt_dm_active_device *dmd,
|
||||
uint32_t flags);
|
||||
uint32_t flags, uint32_t sb_flags);
|
||||
|
||||
int INTEGRITY_activate_dmd_device(struct crypt_device *cd,
|
||||
const char *name,
|
||||
const char *type,
|
||||
struct crypt_dm_active_device *dmd);
|
||||
struct crypt_dm_active_device *dmd,
|
||||
uint32_t sb_flags);
|
||||
#endif
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
*
|
||||
* Copyright (C) 2004 Jana Saout <jana@saout.de>
|
||||
* Copyright (C) 2004-2007 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2019 Milan Broz
|
||||
* Copyright (C) 2009-2021 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2021 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -30,6 +30,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <inttypes.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "nls.h"
|
||||
#include "bitops.h"
|
||||
@@ -77,6 +78,10 @@
|
||||
*_py = NULL; \
|
||||
} while (0)
|
||||
|
||||
#ifndef O_CLOEXEC
|
||||
#define O_CLOEXEC 0
|
||||
#endif
|
||||
|
||||
struct crypt_device;
|
||||
struct luks2_reenc_context;
|
||||
|
||||
@@ -261,4 +266,12 @@ int crypt_compare_dm_devices(struct crypt_device *cd,
|
||||
const struct crypt_dm_active_device *tgt);
|
||||
static inline void *crypt_zalloc(size_t size) { return calloc(1, size); }
|
||||
|
||||
static inline bool uint64_mult_overflow(uint64_t *u, uint64_t b, size_t size)
|
||||
{
|
||||
*u = (uint64_t)b * size;
|
||||
if ((uint64_t)(*u / size) != b)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif /* INTERNAL_H */
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
*
|
||||
* Copyright (C) 2004 Jana Saout <jana@saout.de>
|
||||
* Copyright (C) 2004-2007 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2019 Milan Broz
|
||||
* Copyright (C) 2009-2021 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2021 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -414,6 +414,8 @@ int crypt_get_metadata_size(struct crypt_device *cd,
|
||||
#define CRYPT_TCRYPT "TCRYPT"
|
||||
/** INTEGRITY dm-integrity device */
|
||||
#define CRYPT_INTEGRITY "INTEGRITY"
|
||||
/** BITLK (BitLocker-compatible mode) */
|
||||
#define CRYPT_BITLK "BITLK"
|
||||
|
||||
/** LUKS any version */
|
||||
#define CRYPT_LUKS NULL
|
||||
@@ -505,6 +507,8 @@ struct crypt_params_verity {
|
||||
#define CRYPT_VERITY_CHECK_HASH (1 << 1)
|
||||
/** Create hash - format hash device */
|
||||
#define CRYPT_VERITY_CREATE_HASH (1 << 2)
|
||||
/** Root hash signature required for activation */
|
||||
#define CRYPT_VERITY_ROOT_HASH_SIGNATURE (1 << 3)
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -629,6 +633,30 @@ int crypt_format(struct crypt_device *cd,
|
||||
size_t volume_key_size,
|
||||
void *params);
|
||||
|
||||
/**
|
||||
* Set format compatibility flags.
|
||||
*
|
||||
* @param cd crypt device handle
|
||||
* @param flags CRYPT_COMPATIBILITY_* flags
|
||||
*/
|
||||
void crypt_set_compatibility(struct crypt_device *cd, uint32_t flags);
|
||||
|
||||
/**
|
||||
* Get compatibility flags.
|
||||
*
|
||||
* @param cd crypt device handle
|
||||
*
|
||||
* @returns compatibility flags
|
||||
*/
|
||||
uint32_t crypt_get_compatibility(struct crypt_device *cd);
|
||||
|
||||
/** dm-integrity device uses less effective (legacy) padding (old kernels) */
|
||||
#define CRYPT_COMPAT_LEGACY_INTEGRITY_PADDING (1 << 0)
|
||||
/** dm-integrity device does not protect superblock with HMAC (old kernels) */
|
||||
#define CRYPT_COMPAT_LEGACY_INTEGRITY_HMAC (1 << 1)
|
||||
/** dm-integrity allow recalculating of volumes with HMAC keys (old kernels) */
|
||||
#define CRYPT_COMPAT_LEGACY_INTEGRITY_RECALC (1 << 2)
|
||||
|
||||
/**
|
||||
* Convert to new type for already existing device.
|
||||
*
|
||||
@@ -828,6 +856,20 @@ int crypt_resume_by_keyfile(struct crypt_device *cd,
|
||||
int keyslot,
|
||||
const char *keyfile,
|
||||
size_t keyfile_size);
|
||||
/**
|
||||
* Resume crypt device using provided volume key.
|
||||
*
|
||||
* @param cd crypt device handle
|
||||
* @param name name of device to resume
|
||||
* @param volume_key provided volume key
|
||||
* @param volume_key_size size of volume_key
|
||||
*
|
||||
* @return @e 0 on success or negative errno value otherwise.
|
||||
*/
|
||||
int crypt_resume_by_volume_key(struct crypt_device *cd,
|
||||
const char *name,
|
||||
const char *volume_key,
|
||||
size_t volume_key_size);
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
@@ -1061,6 +1103,16 @@ int crypt_keyslot_destroy(struct crypt_device *cd, int keyslot);
|
||||
#define CRYPT_ACTIVATE_SERIALIZE_MEMORY_HARD_PBKDF (1 << 19)
|
||||
/** dm-integrity: direct writes, use bitmap to track dirty sectors */
|
||||
#define CRYPT_ACTIVATE_NO_JOURNAL_BITMAP (1 << 20)
|
||||
/** device is suspended (key should be wiped from memory), output only */
|
||||
#define CRYPT_ACTIVATE_SUSPENDED (1 << 21)
|
||||
/** use IV sector counted in sector_size instead of default 512 bytes sectors */
|
||||
#define CRYPT_ACTIVATE_IV_LARGE_SECTORS (1 << 22)
|
||||
/** dm-verity: panic_on_corruption flag - panic kernel on corruption */
|
||||
#define CRYPT_ACTIVATE_PANIC_ON_CORRUPTION (1 << 23)
|
||||
/** dm-crypt: bypass internal workqueue and process read requests synchronously. */
|
||||
#define CRYPT_ACTIVATE_NO_READ_WORKQUEUE (1 << 24)
|
||||
/** dm-crypt: bypass internal workqueue and process write requests synchronously. */
|
||||
#define CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE (1 << 25)
|
||||
|
||||
/**
|
||||
* Active device runtime attributes
|
||||
@@ -1252,6 +1304,31 @@ int crypt_activate_by_volume_key(struct crypt_device *cd,
|
||||
size_t volume_key_size,
|
||||
uint32_t flags);
|
||||
|
||||
/**
|
||||
* Activate VERITY device using provided key and optional signature).
|
||||
*
|
||||
* @param cd crypt device handle
|
||||
* @param name name of device to create
|
||||
* @param volume_key provided volume key
|
||||
* @param volume_key_size size of volume_key
|
||||
* @param signature buffer with signature for the key
|
||||
* @param signature_size bsize of signature buffer
|
||||
* @param flags activation flags
|
||||
*
|
||||
* @return @e 0 on success or negative errno value otherwise.
|
||||
*
|
||||
* @note For VERITY the volume key means root hash required for activation.
|
||||
* Because kernel dm-verity is always read only, you have to provide
|
||||
* CRYPT_ACTIVATE_READONLY flag always.
|
||||
*/
|
||||
int crypt_activate_by_signed_key(struct crypt_device *cd,
|
||||
const char *name,
|
||||
const char *volume_key,
|
||||
size_t volume_key_size,
|
||||
const char *signature,
|
||||
size_t signature_size,
|
||||
uint32_t flags);
|
||||
|
||||
/**
|
||||
* Activate device using passphrase stored in kernel keyring.
|
||||
*
|
||||
@@ -1322,6 +1399,7 @@ int crypt_deactivate(struct crypt_device *cd, const char *name);
|
||||
*
|
||||
* @note For TCRYPT cipher chain is the volume key concatenated
|
||||
* for all ciphers in chain.
|
||||
* @note For VERITY the volume key means root hash used for activation.
|
||||
*/
|
||||
int crypt_volume_key_get(struct crypt_device *cd,
|
||||
int keyslot,
|
||||
@@ -1411,11 +1489,11 @@ const char *crypt_get_cipher_mode(struct crypt_device *cd);
|
||||
const char *crypt_get_uuid(struct crypt_device *cd);
|
||||
|
||||
/**
|
||||
* Get path to underlaying device.
|
||||
* Get path to underlying device.
|
||||
*
|
||||
* @param cd crypt device handle
|
||||
*
|
||||
* @return path to underlaying device name
|
||||
* @return path to underlying device name
|
||||
*
|
||||
*/
|
||||
const char *crypt_get_device_name(struct crypt_device *cd);
|
||||
@@ -1425,7 +1503,7 @@ const char *crypt_get_device_name(struct crypt_device *cd);
|
||||
*
|
||||
* @param cd crypt device handle
|
||||
*
|
||||
* @return path to underlaying device name
|
||||
* @return path to underlying device name
|
||||
*
|
||||
*/
|
||||
const char *crypt_get_metadata_device_name(struct crypt_device *cd);
|
||||
@@ -2221,7 +2299,7 @@ int crypt_reencrypt_init_by_keyring(struct crypt_device *cd,
|
||||
* Run data reencryption.
|
||||
*
|
||||
* @param cd crypt device handle
|
||||
* @param progress is a callback funtion reporting device \b size,
|
||||
* @param progress is a callback function reporting device \b size,
|
||||
* current \b offset of reencryption and provided \b usrptr identification
|
||||
*
|
||||
* @return @e 0 on success or negative errno value otherwise.
|
||||
@@ -2251,6 +2329,49 @@ crypt_reencrypt_info crypt_reencrypt_status(struct crypt_device *cd,
|
||||
struct crypt_params_reencrypt *params);
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @defgroup crypt-memory Safe memory helpers functions
|
||||
* @addtogroup crypt-memory
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Allocate safe memory (content is safely wiped on deallocation).
|
||||
*
|
||||
* @param size size of memory in bytes
|
||||
*
|
||||
* @return pointer to allocated memory or @e NULL.
|
||||
*/
|
||||
void *crypt_safe_alloc(size_t size);
|
||||
|
||||
/**
|
||||
* Release safe memory, content is safely wiped.
|
||||
* The pointer must be allocated with @link crypt_safe_alloc @endlink
|
||||
*
|
||||
* @param data pointer to memory to be deallocated
|
||||
*/
|
||||
void crypt_safe_free(void *data);
|
||||
|
||||
/**
|
||||
* Reallocate safe memory (content is copied and safely wiped on deallocation).
|
||||
*
|
||||
* @param data pointer to memory to be deallocated
|
||||
* @param size new size of memory in bytes
|
||||
*
|
||||
* @return pointer to allocated memory or @e NULL.
|
||||
*/
|
||||
void *crypt_safe_realloc(void *data, size_t size);
|
||||
|
||||
/**
|
||||
* Safe clear memory area (compile should not compile this call out).
|
||||
*
|
||||
* @param data pointer to memory to be cleared
|
||||
* @param size size of memory in bytes
|
||||
*/
|
||||
void crypt_safe_memzero(void *data, size_t size);
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -12,6 +12,9 @@ CRYPTSETUP_2.0 {
|
||||
crypt_set_label;
|
||||
crypt_set_data_device;
|
||||
|
||||
crypt_set_compatibility;
|
||||
crypt_get_compatibility;
|
||||
|
||||
crypt_memory_lock;
|
||||
crypt_metadata_locking;
|
||||
crypt_format;
|
||||
@@ -24,6 +27,7 @@ CRYPTSETUP_2.0 {
|
||||
crypt_resume_by_keyfile;
|
||||
crypt_resume_by_keyfile_offset;
|
||||
crypt_resume_by_keyfile_device_offset;
|
||||
crypt_resume_by_volume_key;
|
||||
crypt_free;
|
||||
|
||||
crypt_keyslot_add_by_passphrase;
|
||||
@@ -55,6 +59,7 @@ CRYPTSETUP_2.0 {
|
||||
crypt_activate_by_keyfile_offset;
|
||||
crypt_activate_by_keyfile_device_offset;
|
||||
crypt_activate_by_volume_key;
|
||||
crypt_activate_by_signed_key;
|
||||
crypt_activate_by_keyring;
|
||||
crypt_deactivate;
|
||||
crypt_deactivate_by_name;
|
||||
@@ -118,6 +123,11 @@ CRYPTSETUP_2.0 {
|
||||
crypt_reencrypt_init_by_keyring;
|
||||
crypt_reencrypt;
|
||||
crypt_reencrypt_status;
|
||||
|
||||
crypt_safe_alloc;
|
||||
crypt_safe_realloc;
|
||||
crypt_safe_free;
|
||||
crypt_safe_memzero;
|
||||
local:
|
||||
*;
|
||||
};
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
*
|
||||
* Copyright (C) 2004 Jana Saout <jana@saout.de>
|
||||
* Copyright (C) 2004-2007 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2019 Milan Broz
|
||||
* Copyright (C) 2009-2021 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2021 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -27,7 +27,6 @@
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <libdevmapper.h>
|
||||
#include <fcntl.h>
|
||||
#include <linux/fs.h>
|
||||
#include <uuid/uuid.h>
|
||||
#include <sys/stat.h>
|
||||
@@ -47,6 +46,7 @@
|
||||
#define DM_INTEGRITY_TARGET "integrity"
|
||||
#define DM_LINEAR_TARGET "linear"
|
||||
#define DM_ERROR_TARGET "error"
|
||||
#define DM_ZERO_TARGET "zero"
|
||||
#define RETRY_COUNT 5
|
||||
|
||||
/* Set if DM target versions were probed */
|
||||
@@ -168,6 +168,15 @@ static void _dm_set_crypt_compat(struct crypt_device *cd,
|
||||
_dm_flags |= DM_CAPI_STRING_SUPPORTED;
|
||||
}
|
||||
|
||||
if (_dm_satisfies_version(1, 19, 0, crypt_maj, crypt_min, crypt_patch))
|
||||
_dm_flags |= DM_BITLK_EBOIV_SUPPORTED;
|
||||
|
||||
if (_dm_satisfies_version(1, 20, 0, crypt_maj, crypt_min, crypt_patch))
|
||||
_dm_flags |= DM_BITLK_ELEPHANT_SUPPORTED;
|
||||
|
||||
if (_dm_satisfies_version(1, 22, 0, crypt_maj, crypt_min, crypt_patch))
|
||||
_dm_flags |= DM_CRYPT_NO_WORKQUEUE_SUPPORTED;
|
||||
|
||||
_dm_crypt_checked = true;
|
||||
}
|
||||
|
||||
@@ -196,6 +205,12 @@ static void _dm_set_verity_compat(struct crypt_device *cd,
|
||||
_dm_flags |= DM_VERITY_FEC_SUPPORTED;
|
||||
}
|
||||
|
||||
if (_dm_satisfies_version(1, 5, 0, verity_maj, verity_min, verity_patch))
|
||||
_dm_flags |= DM_VERITY_SIGNATURE_SUPPORTED;
|
||||
|
||||
if (_dm_satisfies_version(1, 7, 0, verity_maj, verity_min, verity_patch))
|
||||
_dm_flags |= DM_VERITY_PANIC_CORRUPTION_SUPPORTED;
|
||||
|
||||
_dm_verity_checked = true;
|
||||
}
|
||||
|
||||
@@ -218,6 +233,15 @@ static void _dm_set_integrity_compat(struct crypt_device *cd,
|
||||
if (_dm_satisfies_version(1, 3, 0, integrity_maj, integrity_min, integrity_patch))
|
||||
_dm_flags |= DM_INTEGRITY_BITMAP_SUPPORTED;
|
||||
|
||||
if (_dm_satisfies_version(1, 4, 0, integrity_maj, integrity_min, integrity_patch))
|
||||
_dm_flags |= DM_INTEGRITY_FIX_PADDING_SUPPORTED;
|
||||
|
||||
if (_dm_satisfies_version(1, 6, 0, integrity_maj, integrity_min, integrity_patch))
|
||||
_dm_flags |= DM_INTEGRITY_DISCARDS_SUPPORTED;
|
||||
|
||||
if (_dm_satisfies_version(1, 7, 0, integrity_maj, integrity_min, integrity_patch))
|
||||
_dm_flags |= DM_INTEGRITY_FIX_HMAC_SUPPORTED;
|
||||
|
||||
_dm_integrity_checked = true;
|
||||
}
|
||||
|
||||
@@ -265,7 +289,7 @@ static int _dm_check_versions(struct crypt_device *cd, dm_target_type target_typ
|
||||
if ((target_type == DM_CRYPT && _dm_crypt_checked) ||
|
||||
(target_type == DM_VERITY && _dm_verity_checked) ||
|
||||
(target_type == DM_INTEGRITY && _dm_integrity_checked) ||
|
||||
(target_type == DM_LINEAR) ||
|
||||
(target_type == DM_LINEAR) || (target_type == DM_ZERO) ||
|
||||
(_dm_crypt_checked && _dm_verity_checked && _dm_integrity_checked))
|
||||
return 1;
|
||||
|
||||
@@ -346,7 +370,7 @@ int dm_flags(struct crypt_device *cd, dm_target_type target, uint32_t *flags)
|
||||
if ((target == DM_CRYPT && _dm_crypt_checked) ||
|
||||
(target == DM_VERITY && _dm_verity_checked) ||
|
||||
(target == DM_INTEGRITY && _dm_integrity_checked) ||
|
||||
(target == DM_LINEAR)) /* nothing to check with linear */
|
||||
(target == DM_LINEAR) || (target == DM_ZERO)) /* nothing to check */
|
||||
return 0;
|
||||
|
||||
return -ENODEV;
|
||||
@@ -600,6 +624,12 @@ static char *get_dm_crypt_params(const struct dm_target *tgt, uint32_t flags)
|
||||
num_options++;
|
||||
if (flags & CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS)
|
||||
num_options++;
|
||||
if (flags & CRYPT_ACTIVATE_NO_READ_WORKQUEUE)
|
||||
num_options++;
|
||||
if (flags & CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE)
|
||||
num_options++;
|
||||
if (flags & CRYPT_ACTIVATE_IV_LARGE_SECTORS)
|
||||
num_options++;
|
||||
if (tgt->u.crypt.integrity)
|
||||
num_options++;
|
||||
|
||||
@@ -610,22 +640,27 @@ static char *get_dm_crypt_params(const struct dm_target *tgt, uint32_t flags)
|
||||
*sector_feature = '\0';
|
||||
|
||||
if (num_options) {
|
||||
snprintf(features, sizeof(features)-1, " %d%s%s%s%s%s", num_options,
|
||||
snprintf(features, sizeof(features)-1, " %d%s%s%s%s%s%s%s%s", num_options,
|
||||
(flags & CRYPT_ACTIVATE_ALLOW_DISCARDS) ? " allow_discards" : "",
|
||||
(flags & CRYPT_ACTIVATE_SAME_CPU_CRYPT) ? " same_cpu_crypt" : "",
|
||||
(flags & CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS) ? " submit_from_crypt_cpus" : "",
|
||||
(flags & CRYPT_ACTIVATE_NO_READ_WORKQUEUE) ? " no_read_workqueue" : "",
|
||||
(flags & CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE) ? " no_write_workqueue" : "",
|
||||
(flags & CRYPT_ACTIVATE_IV_LARGE_SECTORS) ? " iv_large_sectors" : "",
|
||||
sector_feature, integrity_dm);
|
||||
} else
|
||||
*features = '\0';
|
||||
|
||||
if (!strncmp(cipher_dm, "cipher_null-", 12))
|
||||
if (crypt_is_cipher_null(cipher_dm))
|
||||
null_cipher = 1;
|
||||
|
||||
if (flags & CRYPT_ACTIVATE_KEYRING_KEY) {
|
||||
if (null_cipher)
|
||||
hexkey = crypt_safe_alloc(2);
|
||||
else if (flags & CRYPT_ACTIVATE_KEYRING_KEY) {
|
||||
keystr_len = strlen(tgt->u.crypt.vk->key_description) + int_log10(tgt->u.crypt.vk->keylength) + 10;
|
||||
hexkey = crypt_safe_alloc(keystr_len);
|
||||
} else
|
||||
hexkey = crypt_safe_alloc(null_cipher ? 2 : (tgt->u.crypt.vk->keylength * 2 + 1));
|
||||
hexkey = crypt_safe_alloc(tgt->u.crypt.vk->keylength * 2 + 1);
|
||||
|
||||
if (!hexkey)
|
||||
return NULL;
|
||||
@@ -667,7 +702,7 @@ static char *get_dm_verity_params(const struct dm_target *tgt, uint32_t flags)
|
||||
int max_size, r, num_options = 0;
|
||||
struct crypt_params_verity *vp;
|
||||
char *params = NULL, *hexroot = NULL, *hexsalt = NULL;
|
||||
char features[256], fec_features[256];
|
||||
char features[256], fec_features[256], verity_verify_args[512+32];
|
||||
|
||||
if (!tgt || !tgt->u.verity.vp)
|
||||
return NULL;
|
||||
@@ -675,14 +710,19 @@ static char *get_dm_verity_params(const struct dm_target *tgt, uint32_t flags)
|
||||
vp = tgt->u.verity.vp;
|
||||
|
||||
/* These flags are not compatible */
|
||||
if ((flags & CRYPT_ACTIVATE_RESTART_ON_CORRUPTION) &&
|
||||
(flags & CRYPT_ACTIVATE_PANIC_ON_CORRUPTION))
|
||||
flags &= ~CRYPT_ACTIVATE_RESTART_ON_CORRUPTION;
|
||||
if ((flags & CRYPT_ACTIVATE_IGNORE_CORRUPTION) &&
|
||||
(flags & CRYPT_ACTIVATE_RESTART_ON_CORRUPTION))
|
||||
(flags & (CRYPT_ACTIVATE_RESTART_ON_CORRUPTION|CRYPT_ACTIVATE_PANIC_ON_CORRUPTION)))
|
||||
flags &= ~CRYPT_ACTIVATE_IGNORE_CORRUPTION;
|
||||
|
||||
if (flags & CRYPT_ACTIVATE_IGNORE_CORRUPTION)
|
||||
num_options++;
|
||||
if (flags & CRYPT_ACTIVATE_RESTART_ON_CORRUPTION)
|
||||
num_options++;
|
||||
if (flags & CRYPT_ACTIVATE_PANIC_ON_CORRUPTION)
|
||||
num_options++;
|
||||
if (flags & CRYPT_ACTIVATE_IGNORE_ZERO_BLOCKS)
|
||||
num_options++;
|
||||
if (flags & CRYPT_ACTIVATE_CHECK_AT_MOST_ONCE)
|
||||
@@ -693,14 +733,22 @@ static char *get_dm_verity_params(const struct dm_target *tgt, uint32_t flags)
|
||||
snprintf(fec_features, sizeof(fec_features)-1,
|
||||
" use_fec_from_device %s fec_start %" PRIu64 " fec_blocks %" PRIu64 " fec_roots %" PRIu32,
|
||||
device_block_path(tgt->u.verity.fec_device), tgt->u.verity.fec_offset,
|
||||
vp->data_size + tgt->u.verity.hash_blocks, vp->fec_roots);
|
||||
tgt->u.verity.fec_blocks, vp->fec_roots);
|
||||
} else
|
||||
*fec_features = '\0';
|
||||
|
||||
if (tgt->u.verity.root_hash_sig_key_desc) {
|
||||
num_options += 2;
|
||||
snprintf(verity_verify_args, sizeof(verity_verify_args)-1,
|
||||
" root_hash_sig_key_desc %s", tgt->u.verity.root_hash_sig_key_desc);
|
||||
} else
|
||||
*verity_verify_args = '\0';
|
||||
|
||||
if (num_options)
|
||||
snprintf(features, sizeof(features)-1, " %d%s%s%s%s", num_options,
|
||||
snprintf(features, sizeof(features)-1, " %d%s%s%s%s%s", num_options,
|
||||
(flags & CRYPT_ACTIVATE_IGNORE_CORRUPTION) ? " ignore_corruption" : "",
|
||||
(flags & CRYPT_ACTIVATE_RESTART_ON_CORRUPTION) ? " restart_on_corruption" : "",
|
||||
(flags & CRYPT_ACTIVATE_PANIC_ON_CORRUPTION) ? " panic_on_corruption" : "",
|
||||
(flags & CRYPT_ACTIVATE_IGNORE_ZERO_BLOCKS) ? " ignore_zero_blocks" : "",
|
||||
(flags & CRYPT_ACTIVATE_CHECK_AT_MOST_ONCE) ? " check_at_most_once" : "");
|
||||
else
|
||||
@@ -722,19 +770,22 @@ static char *get_dm_verity_params(const struct dm_target *tgt, uint32_t flags)
|
||||
max_size = strlen(hexroot) + strlen(hexsalt) +
|
||||
strlen(device_block_path(tgt->data_device)) +
|
||||
strlen(device_block_path(tgt->u.verity.hash_device)) +
|
||||
strlen(vp->hash_name) + strlen(features) + strlen(fec_features) + 128;
|
||||
strlen(vp->hash_name) + strlen(features) + strlen(fec_features) + 128 +
|
||||
strlen(verity_verify_args);
|
||||
|
||||
params = crypt_safe_alloc(max_size);
|
||||
if (!params)
|
||||
goto out;
|
||||
|
||||
r = snprintf(params, max_size,
|
||||
"%u %s %s %u %u %" PRIu64 " %" PRIu64 " %s %s %s%s%s",
|
||||
"%u %s %s %u %u %" PRIu64 " %" PRIu64 " %s %s %s%s%s%s",
|
||||
vp->hash_type, device_block_path(tgt->data_device),
|
||||
device_block_path(tgt->u.verity.hash_device),
|
||||
vp->data_block_size, vp->hash_block_size,
|
||||
vp->data_size, tgt->u.verity.hash_offset,
|
||||
vp->hash_name, hexroot, hexsalt, features, fec_features);
|
||||
vp->hash_name, hexroot, hexsalt, features, fec_features,
|
||||
verity_verify_args);
|
||||
|
||||
if (r < 0 || r >= max_size) {
|
||||
crypt_safe_free(params);
|
||||
params = NULL;
|
||||
@@ -867,12 +918,36 @@ static char *get_dm_integrity_params(const struct dm_target *tgt, uint32_t flags
|
||||
crypt_safe_free(hexkey);
|
||||
}
|
||||
|
||||
if (tgt->u.integrity.fix_padding) {
|
||||
num_options++;
|
||||
snprintf(feature, sizeof(feature), "fix_padding ");
|
||||
strncat(features, feature, sizeof(features) - strlen(features) - 1);
|
||||
}
|
||||
|
||||
if (tgt->u.integrity.fix_hmac) {
|
||||
num_options++;
|
||||
snprintf(feature, sizeof(feature), "fix_hmac ");
|
||||
strncat(features, feature, sizeof(features) - strlen(features) - 1);
|
||||
}
|
||||
|
||||
if (tgt->u.integrity.legacy_recalc) {
|
||||
num_options++;
|
||||
snprintf(feature, sizeof(feature), "legacy_recalculate ");
|
||||
strncat(features, feature, sizeof(features) - strlen(features) - 1);
|
||||
}
|
||||
|
||||
if (flags & CRYPT_ACTIVATE_RECALCULATE) {
|
||||
num_options++;
|
||||
snprintf(feature, sizeof(feature), "recalculate ");
|
||||
strncat(features, feature, sizeof(features) - strlen(features) - 1);
|
||||
}
|
||||
|
||||
if (flags & CRYPT_ACTIVATE_ALLOW_DISCARDS) {
|
||||
num_options++;
|
||||
snprintf(feature, sizeof(feature), "allow_discards ");
|
||||
strncat(features, feature, sizeof(features) - strlen(features) - 1);
|
||||
}
|
||||
|
||||
if (tgt->u.integrity.meta_device) {
|
||||
num_options++;
|
||||
snprintf(feature, sizeof(feature), "meta_device:%s ",
|
||||
@@ -922,6 +997,16 @@ static char *get_dm_linear_params(const struct dm_target *tgt, uint32_t flags)
|
||||
return params;
|
||||
}
|
||||
|
||||
static char *get_dm_zero_params(const struct dm_target *tgt, uint32_t flags)
|
||||
{
|
||||
char *params = crypt_safe_alloc(1);
|
||||
if (!params)
|
||||
return NULL;
|
||||
|
||||
params[0] = 0;
|
||||
return params;
|
||||
}
|
||||
|
||||
/* DM helpers */
|
||||
static int _dm_remove(const char *name, int udev_wait, int deferred)
|
||||
{
|
||||
@@ -1195,6 +1280,9 @@ static int _add_dm_targets(struct dm_task *dmt, struct crypt_dm_active_device *d
|
||||
case DM_LINEAR:
|
||||
target = DM_LINEAR_TARGET;
|
||||
break;
|
||||
case DM_ZERO:
|
||||
target = DM_ZERO_TARGET;
|
||||
break;
|
||||
default:
|
||||
return -ENOTSUP;
|
||||
}
|
||||
@@ -1233,6 +1321,8 @@ static int _create_dm_targets_params(struct crypt_dm_active_device *dmd)
|
||||
tgt->params = get_dm_integrity_params(tgt, dmd->flags);
|
||||
else if (tgt->type == DM_LINEAR)
|
||||
tgt->params = get_dm_linear_params(tgt, dmd->flags);
|
||||
else if (tgt->type == DM_ZERO)
|
||||
tgt->params = get_dm_zero_params(tgt, dmd->flags);
|
||||
else {
|
||||
r = -ENOTSUP;
|
||||
goto err;
|
||||
@@ -1251,6 +1341,12 @@ err:
|
||||
return r;
|
||||
}
|
||||
|
||||
static bool dm_device_exists(struct crypt_device *cd, const char *name)
|
||||
{
|
||||
int r = dm_status_device(cd, name);
|
||||
return (r >= 0 || r == -EEXIST);
|
||||
}
|
||||
|
||||
static int _dm_create_device(struct crypt_device *cd, const char *name, const char *type,
|
||||
const char *uuid, struct crypt_dm_active_device *dmd)
|
||||
{
|
||||
@@ -1300,8 +1396,11 @@ static int _dm_create_device(struct crypt_device *cd, const char *name, const ch
|
||||
if (_dm_use_udev() && !_dm_task_set_cookie(dmt, &cookie, udev_flags))
|
||||
goto out;
|
||||
|
||||
if (!dm_task_run(dmt))
|
||||
if (!dm_task_run(dmt)) {
|
||||
if (dm_device_exists(cd, name))
|
||||
r = -EEXIST;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (dm_task_get_info(dmt, &dmi))
|
||||
r = 0;
|
||||
@@ -1454,10 +1553,13 @@ static void _dm_target_free_query_path(struct crypt_device *cd, struct dm_target
|
||||
crypt_free_verity_params(tgt->u.verity.vp);
|
||||
device_free(cd, tgt->u.verity.hash_device);
|
||||
free(CONST_CAST(void*)tgt->u.verity.root_hash);
|
||||
free(CONST_CAST(void*)tgt->u.verity.root_hash_sig_key_desc);
|
||||
/* fall through */
|
||||
case DM_LINEAR:
|
||||
/* fall through */
|
||||
case DM_ERROR:
|
||||
/* fall through */
|
||||
case DM_ZERO:
|
||||
break;
|
||||
default:
|
||||
log_err(cd, _("Unknown dm target type."));
|
||||
@@ -1522,7 +1624,7 @@ static int check_retry(struct crypt_device *cd, uint32_t *dmd_flags, uint32_t dm
|
||||
/* If kernel keyring is not supported load key directly in dm-crypt */
|
||||
if ((*dmd_flags & CRYPT_ACTIVATE_KEYRING_KEY) &&
|
||||
!(dmt_flags & DM_KERNEL_KEYRING_SUPPORTED)) {
|
||||
log_dbg(cd, "dm-crypt doesn't support kernel keyring");
|
||||
log_dbg(cd, "dm-crypt does not support kernel keyring");
|
||||
*dmd_flags = *dmd_flags & ~CRYPT_ACTIVATE_KEYRING_KEY;
|
||||
ret = 1;
|
||||
}
|
||||
@@ -1530,11 +1632,19 @@ static int check_retry(struct crypt_device *cd, uint32_t *dmd_flags, uint32_t dm
|
||||
/* Drop performance options if not supported */
|
||||
if ((*dmd_flags & (CRYPT_ACTIVATE_SAME_CPU_CRYPT | CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS)) &&
|
||||
!(dmt_flags & (DM_SAME_CPU_CRYPT_SUPPORTED | DM_SUBMIT_FROM_CRYPT_CPUS_SUPPORTED))) {
|
||||
log_dbg(cd, "dm-crypt doesn't support performance options");
|
||||
log_dbg(cd, "dm-crypt does not support performance options");
|
||||
*dmd_flags = *dmd_flags & ~(CRYPT_ACTIVATE_SAME_CPU_CRYPT | CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS);
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
/* Drop no workqueue options if not supported */
|
||||
if ((*dmd_flags & (CRYPT_ACTIVATE_NO_READ_WORKQUEUE | CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE)) &&
|
||||
!(dmt_flags & DM_CRYPT_NO_WORKQUEUE_SUPPORTED)) {
|
||||
log_dbg(cd, "dm-crypt does not support performance options");
|
||||
*dmd_flags = *dmd_flags & ~(CRYPT_ACTIVATE_NO_READ_WORKQUEUE | CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE);
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1556,14 +1666,30 @@ int dm_create_device(struct crypt_device *cd, const char *name,
|
||||
if (r < 0 && dm_flags(cd, dmd->segment.type, &dmt_flags))
|
||||
goto out;
|
||||
|
||||
if (r && (dmd->segment.type == DM_CRYPT || dmd->segment.type == DM_LINEAR) && check_retry(cd, &dmd->flags, dmt_flags))
|
||||
if (r && (dmd->segment.type == DM_CRYPT || dmd->segment.type == DM_LINEAR || dmd->segment.type == DM_ZERO) &&
|
||||
check_retry(cd, &dmd->flags, dmt_flags)) {
|
||||
log_dbg(cd, "Retrying open without incompatible options.");
|
||||
r = _dm_create_device(cd, name, type, dmd->uuid, dmd);
|
||||
}
|
||||
|
||||
/*
|
||||
* Print warning if activating dm-crypt cipher_null device unless it's reencryption helper or
|
||||
* keyslot encryption helper device (LUKS1 cipher_null devices).
|
||||
*/
|
||||
if (!r && !(dmd->flags & CRYPT_ACTIVATE_PRIVATE) && single_segment(dmd) && dmd->segment.type == DM_CRYPT &&
|
||||
crypt_is_cipher_null(dmd->segment.u.crypt.cipher))
|
||||
log_dbg(cd, "Activated dm-crypt device with cipher_null. Device is not encrypted.");
|
||||
|
||||
if (r == -EINVAL &&
|
||||
dmd->flags & (CRYPT_ACTIVATE_SAME_CPU_CRYPT|CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS) &&
|
||||
!(dmt_flags & (DM_SAME_CPU_CRYPT_SUPPORTED|DM_SUBMIT_FROM_CRYPT_CPUS_SUPPORTED)))
|
||||
log_err(cd, _("Requested dm-crypt performance options are not supported."));
|
||||
|
||||
if (r == -EINVAL &&
|
||||
dmd->flags & (CRYPT_ACTIVATE_NO_READ_WORKQUEUE | CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE) &&
|
||||
!(dmt_flags & DM_CRYPT_NO_WORKQUEUE_SUPPORTED))
|
||||
log_err(cd, _("Requested dm-crypt performance options are not supported."));
|
||||
|
||||
if (r == -EINVAL && dmd->flags & (CRYPT_ACTIVATE_IGNORE_CORRUPTION|
|
||||
CRYPT_ACTIVATE_RESTART_ON_CORRUPTION|
|
||||
CRYPT_ACTIVATE_IGNORE_ZERO_BLOCKS|
|
||||
@@ -1571,6 +1697,10 @@ int dm_create_device(struct crypt_device *cd, const char *name,
|
||||
!(dmt_flags & DM_VERITY_ON_CORRUPTION_SUPPORTED))
|
||||
log_err(cd, _("Requested dm-verity data corruption handling options are not supported."));
|
||||
|
||||
if (r == -EINVAL && dmd->flags & CRYPT_ACTIVATE_PANIC_ON_CORRUPTION &&
|
||||
!(dmt_flags & DM_VERITY_PANIC_CORRUPTION_SUPPORTED))
|
||||
log_err(cd, _("Requested dm-verity data corruption handling options are not supported."));
|
||||
|
||||
if (r == -EINVAL && dmd->segment.type == DM_VERITY &&
|
||||
dmd->segment.u.verity.fec_device && !(dmt_flags & DM_VERITY_FEC_SUPPORTED))
|
||||
log_err(cd, _("Requested dm-verity FEC options are not supported."));
|
||||
@@ -1586,6 +1716,10 @@ int dm_create_device(struct crypt_device *cd, const char *name,
|
||||
!(dmt_flags & DM_INTEGRITY_RECALC_SUPPORTED))
|
||||
log_err(cd, _("Requested automatic recalculation of integrity tags is not supported."));
|
||||
|
||||
if (r == -EINVAL && dmd->segment.type == DM_INTEGRITY && (dmd->flags & CRYPT_ACTIVATE_ALLOW_DISCARDS) &&
|
||||
!(dmt_flags & DM_INTEGRITY_DISCARDS_SUPPORTED))
|
||||
log_err(cd, _("Discard/TRIM is not supported."));
|
||||
|
||||
if (r == -EINVAL && dmd->segment.type == DM_INTEGRITY && (dmd->flags & CRYPT_ACTIVATE_NO_JOURNAL_BITMAP) &&
|
||||
!(dmt_flags & DM_INTEGRITY_BITMAP_SUPPORTED))
|
||||
log_err(cd, _("Requested dm-integrity bitmap mode is not supported."));
|
||||
@@ -1613,11 +1747,17 @@ int dm_reload_device(struct crypt_device *cd, const char *name,
|
||||
|
||||
if (r == -EINVAL && (dmd->segment.type == DM_CRYPT || dmd->segment.type == DM_LINEAR)) {
|
||||
if ((dmd->flags & (CRYPT_ACTIVATE_SAME_CPU_CRYPT|CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS)) &&
|
||||
!dm_flags(cd, DM_CRYPT, &dmt_flags) && !(dmt_flags & (DM_SAME_CPU_CRYPT_SUPPORTED|DM_SUBMIT_FROM_CRYPT_CPUS_SUPPORTED)))
|
||||
!dm_flags(cd, DM_CRYPT, &dmt_flags) && !(dmt_flags & (DM_SAME_CPU_CRYPT_SUPPORTED | DM_SUBMIT_FROM_CRYPT_CPUS_SUPPORTED)))
|
||||
log_err(cd, _("Requested dm-crypt performance options are not supported."));
|
||||
if ((dmd->flags & (CRYPT_ACTIVATE_NO_READ_WORKQUEUE | CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE)) &&
|
||||
!dm_flags(cd, DM_CRYPT, &dmt_flags) && !(dmt_flags & DM_CRYPT_NO_WORKQUEUE_SUPPORTED))
|
||||
log_err(cd, _("Requested dm-crypt performance options are not supported."));
|
||||
if ((dmd->flags & CRYPT_ACTIVATE_ALLOW_DISCARDS) &&
|
||||
!dm_flags(cd, DM_CRYPT, &dmt_flags) && !(dmt_flags & DM_DISCARDS_SUPPORTED))
|
||||
log_err(cd, _("Discard/TRIM is not supported."));
|
||||
if ((dmd->flags & CRYPT_ACTIVATE_ALLOW_DISCARDS) &&
|
||||
!dm_flags(cd, DM_INTEGRITY, &dmt_flags) && !(dmt_flags & DM_INTEGRITY_DISCARDS_SUPPORTED))
|
||||
log_err(cd, _("Discard/TRIM is not supported."));
|
||||
}
|
||||
|
||||
if (!r && resume)
|
||||
@@ -1655,6 +1795,7 @@ static int dm_status_dmi(const char *name, struct dm_info *dmi,
|
||||
goto out;
|
||||
}
|
||||
|
||||
r = -EEXIST;
|
||||
dm_get_next_target(dmt, NULL, &start, &length,
|
||||
&target_type, ¶ms);
|
||||
|
||||
@@ -1669,6 +1810,7 @@ static int dm_status_dmi(const char *name, struct dm_info *dmi,
|
||||
strcmp(target_type, DM_VERITY_TARGET) &&
|
||||
strcmp(target_type, DM_INTEGRITY_TARGET) &&
|
||||
strcmp(target_type, DM_LINEAR_TARGET) &&
|
||||
strcmp(target_type, DM_ZERO_TARGET) &&
|
||||
strcmp(target_type, DM_ERROR_TARGET)))
|
||||
goto out;
|
||||
r = 0;
|
||||
@@ -1852,6 +1994,12 @@ static int _dm_target_query_crypt(struct crypt_device *cd, uint32_t get_flags,
|
||||
*act_flags |= CRYPT_ACTIVATE_SAME_CPU_CRYPT;
|
||||
else if (!strcasecmp(arg, "submit_from_crypt_cpus"))
|
||||
*act_flags |= CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS;
|
||||
else if (!strcasecmp(arg, "no_read_workqueue"))
|
||||
*act_flags |= CRYPT_ACTIVATE_NO_READ_WORKQUEUE;
|
||||
else if (!strcasecmp(arg, "no_write_workqueue"))
|
||||
*act_flags |= CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE;
|
||||
else if (!strcasecmp(arg, "iv_large_sectors"))
|
||||
*act_flags |= CRYPT_ACTIVATE_IV_LARGE_SECTORS;
|
||||
else if (sscanf(arg, "integrity:%u:", &val) == 1) {
|
||||
tgt->u.crypt.tag_size = val;
|
||||
rintegrity = strchr(arg + strlen("integrity:"), ':');
|
||||
@@ -1957,6 +2105,7 @@ static int _dm_target_query_verity(struct crypt_device *cd,
|
||||
int r;
|
||||
struct device *data_device = NULL, *hash_device = NULL, *fec_device = NULL;
|
||||
char *hash_name = NULL, *root_hash = NULL, *salt = NULL, *fec_dev_str = NULL;
|
||||
char *root_hash_sig_key_desc = NULL;
|
||||
|
||||
if (get_flags & DM_ACTIVE_VERITY_PARAMS) {
|
||||
vp = crypt_zalloc(sizeof(*vp));
|
||||
@@ -2099,6 +2248,8 @@ static int _dm_target_query_verity(struct crypt_device *cd,
|
||||
*act_flags |= CRYPT_ACTIVATE_IGNORE_CORRUPTION;
|
||||
else if (!strcasecmp(arg, "restart_on_corruption"))
|
||||
*act_flags |= CRYPT_ACTIVATE_RESTART_ON_CORRUPTION;
|
||||
else if (!strcasecmp(arg, "panic_on_corruption"))
|
||||
*act_flags |= CRYPT_ACTIVATE_PANIC_ON_CORRUPTION;
|
||||
else if (!strcasecmp(arg, "ignore_zero_blocks"))
|
||||
*act_flags |= CRYPT_ACTIVATE_IGNORE_ZERO_BLOCKS;
|
||||
else if (!strcasecmp(arg, "check_at_most_once"))
|
||||
@@ -2140,6 +2291,15 @@ static int _dm_target_query_verity(struct crypt_device *cd,
|
||||
if (vp)
|
||||
vp->fec_roots = val32;
|
||||
i++;
|
||||
} else if (!strcasecmp(arg, "root_hash_sig_key_desc")) {
|
||||
str = strsep(¶ms, " ");
|
||||
if (!str)
|
||||
goto err;
|
||||
if (!root_hash_sig_key_desc)
|
||||
root_hash_sig_key_desc = strdup(str);
|
||||
i++;
|
||||
if (vp)
|
||||
vp->flags |= CRYPT_VERITY_ROOT_HASH_SIGNATURE;
|
||||
} else /* unknown option */
|
||||
goto err;
|
||||
}
|
||||
@@ -2165,11 +2325,15 @@ static int _dm_target_query_verity(struct crypt_device *cd,
|
||||
vp->salt = salt;
|
||||
if (vp && fec_dev_str)
|
||||
vp->fec_device = fec_dev_str;
|
||||
if (root_hash_sig_key_desc)
|
||||
tgt->u.verity.root_hash_sig_key_desc = root_hash_sig_key_desc;
|
||||
|
||||
return 0;
|
||||
err:
|
||||
device_free(cd, data_device);
|
||||
device_free(cd, hash_device);
|
||||
device_free(cd, fec_device);
|
||||
free(root_hash_sig_key_desc);
|
||||
free(root_hash);
|
||||
free(hash_name);
|
||||
free(salt);
|
||||
@@ -2334,6 +2498,14 @@ static int _dm_target_query_integrity(struct crypt_device *cd,
|
||||
}
|
||||
} else if (!strcmp(arg, "recalculate")) {
|
||||
*act_flags |= CRYPT_ACTIVATE_RECALCULATE;
|
||||
} else if (!strcmp(arg, "fix_padding")) {
|
||||
tgt->u.integrity.fix_padding = true;
|
||||
} else if (!strcmp(arg, "fix_hmac")) {
|
||||
tgt->u.integrity.fix_hmac = true;
|
||||
} else if (!strcmp(arg, "legacy_recalculate")) {
|
||||
tgt->u.integrity.legacy_recalc = true;
|
||||
} else if (!strcmp(arg, "allow_discards")) {
|
||||
*act_flags |= CRYPT_ACTIVATE_ALLOW_DISCARDS;
|
||||
} else /* unknown option */
|
||||
goto err;
|
||||
}
|
||||
@@ -2416,6 +2588,14 @@ static int _dm_target_query_error(struct crypt_device *cd, struct dm_target *tgt
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _dm_target_query_zero(struct crypt_device *cd, struct dm_target *tgt)
|
||||
{
|
||||
tgt->type = DM_ZERO;
|
||||
tgt->direction = TARGET_QUERY;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* on error retval has to be negative
|
||||
*
|
||||
@@ -2437,6 +2617,8 @@ static int dm_target_query(struct crypt_device *cd, struct dm_target *tgt, const
|
||||
r = _dm_target_query_linear(cd, tgt, get_flags, params);
|
||||
else if (!strcmp(target_type, DM_ERROR_TARGET))
|
||||
r = _dm_target_query_error(cd, tgt);
|
||||
else if (!strcmp(target_type, DM_ZERO_TARGET))
|
||||
r = _dm_target_query_zero(cd, tgt);
|
||||
|
||||
if (!r) {
|
||||
tgt->offset = *start;
|
||||
@@ -2519,6 +2701,9 @@ static int _dm_query_device(struct crypt_device *cd, const char *name,
|
||||
if (dmi.read_only)
|
||||
dmd->flags |= CRYPT_ACTIVATE_READONLY;
|
||||
|
||||
if (dmi.suspended)
|
||||
dmd->flags |= CRYPT_ACTIVATE_SUSPENDED;
|
||||
|
||||
tmp_uuid = dm_task_get_uuid(dmt);
|
||||
if (!tmp_uuid)
|
||||
dmd->flags |= CRYPT_ACTIVATE_NO_UUID;
|
||||
@@ -2566,6 +2751,7 @@ int dm_query_device(struct crypt_device *cd, const char *name,
|
||||
|
||||
static int _process_deps(struct crypt_device *cd, const char *prefix, struct dm_deps *deps, char **names, size_t names_offset, size_t names_length)
|
||||
{
|
||||
#if HAVE_DECL_DM_DEVICE_GET_NAME
|
||||
struct crypt_dm_active_device dmd;
|
||||
char dmname[PATH_MAX];
|
||||
unsigned i;
|
||||
@@ -2604,6 +2790,9 @@ static int _process_deps(struct crypt_device *cd, const char *prefix, struct dm_
|
||||
}
|
||||
|
||||
return count;
|
||||
#else
|
||||
return -EINVAL;
|
||||
#endif
|
||||
}
|
||||
|
||||
int dm_device_deps(struct crypt_device *cd, const char *name, const char *prefix, char **names, size_t names_length)
|
||||
@@ -2754,7 +2943,9 @@ int dm_resume_and_reinstate_key(struct crypt_device *cd, const char *name,
|
||||
if (!(dmt_flags & DM_KEY_WIPE_SUPPORTED))
|
||||
goto out;
|
||||
|
||||
if (vk->key_description)
|
||||
if (!vk->keylength)
|
||||
msg_size = 11; // key set -
|
||||
else if (vk->key_description)
|
||||
msg_size = strlen(vk->key_description) + int_log10(vk->keylength) + 18;
|
||||
else
|
||||
msg_size = vk->keylength * 2 + 10; // key set <key>
|
||||
@@ -2766,7 +2957,9 @@ int dm_resume_and_reinstate_key(struct crypt_device *cd, const char *name,
|
||||
}
|
||||
|
||||
strcpy(msg, "key set ");
|
||||
if (vk->key_description)
|
||||
if (!vk->keylength)
|
||||
snprintf(msg + 8, msg_size - 8, "-");
|
||||
else if (vk->key_description)
|
||||
snprintf(msg + 8, msg_size - 8, ":%zu:logon:%s", vk->keylength, vk->key_description);
|
||||
else
|
||||
hex_key(&msg[8], vk->keylength, vk->key);
|
||||
@@ -2841,8 +3034,8 @@ err:
|
||||
|
||||
int dm_verity_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t seg_size,
|
||||
struct device *data_device, struct device *hash_device, struct device *fec_device,
|
||||
const char *root_hash, uint32_t root_hash_size, uint64_t hash_offset_block,
|
||||
uint64_t hash_blocks, struct crypt_params_verity *vp)
|
||||
const char *root_hash, uint32_t root_hash_size, const char* root_hash_sig_key_desc,
|
||||
uint64_t hash_offset_block, uint64_t fec_blocks, struct crypt_params_verity *vp)
|
||||
{
|
||||
if (!data_device || !hash_device || !vp)
|
||||
return -EINVAL;
|
||||
@@ -2857,24 +3050,30 @@ int dm_verity_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t se
|
||||
tgt->u.verity.fec_device = fec_device;
|
||||
tgt->u.verity.root_hash = root_hash;
|
||||
tgt->u.verity.root_hash_size = root_hash_size;
|
||||
tgt->u.verity.root_hash_sig_key_desc = root_hash_sig_key_desc;
|
||||
tgt->u.verity.hash_offset = hash_offset_block;
|
||||
tgt->u.verity.fec_offset = vp->fec_area_offset / vp->hash_block_size;
|
||||
tgt->u.verity.hash_blocks = hash_blocks;
|
||||
tgt->u.verity.fec_blocks = fec_blocks;
|
||||
tgt->u.verity.vp = vp;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dm_integrity_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t seg_size,
|
||||
int dm_integrity_target_set(struct crypt_device *cd,
|
||||
struct dm_target *tgt, uint64_t seg_offset, uint64_t seg_size,
|
||||
struct device *meta_device,
|
||||
struct device *data_device, uint64_t tag_size, uint64_t offset,
|
||||
uint32_t sector_size, struct volume_key *vk,
|
||||
struct volume_key *journal_crypt_key, struct volume_key *journal_mac_key,
|
||||
const struct crypt_params_integrity *ip)
|
||||
{
|
||||
uint32_t dmi_flags;
|
||||
|
||||
if (!data_device)
|
||||
return -EINVAL;
|
||||
|
||||
_dm_check_versions(cd, DM_INTEGRITY);
|
||||
|
||||
tgt->type = DM_INTEGRITY;
|
||||
tgt->direction = TARGET_SET;
|
||||
tgt->offset = seg_offset;
|
||||
@@ -2890,6 +3089,20 @@ int dm_integrity_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t
|
||||
tgt->u.integrity.journal_crypt_key = journal_crypt_key;
|
||||
tgt->u.integrity.journal_integrity_key = journal_mac_key;
|
||||
|
||||
if (!dm_flags(cd, DM_INTEGRITY, &dmi_flags) &&
|
||||
(dmi_flags & DM_INTEGRITY_FIX_PADDING_SUPPORTED) &&
|
||||
!(crypt_get_compatibility(cd) & CRYPT_COMPAT_LEGACY_INTEGRITY_PADDING))
|
||||
tgt->u.integrity.fix_padding = true;
|
||||
|
||||
if (!dm_flags(cd, DM_INTEGRITY, &dmi_flags) &&
|
||||
(dmi_flags & DM_INTEGRITY_FIX_HMAC_SUPPORTED) &&
|
||||
!(crypt_get_compatibility(cd) & CRYPT_COMPAT_LEGACY_INTEGRITY_HMAC))
|
||||
tgt->u.integrity.fix_hmac = true;
|
||||
|
||||
/* This flag can be backported, just try to set it always */
|
||||
if (crypt_get_compatibility(cd) & CRYPT_COMPAT_LEGACY_INTEGRITY_RECALC)
|
||||
tgt->u.integrity.legacy_recalc = true;
|
||||
|
||||
if (ip) {
|
||||
tgt->u.integrity.journal_size = ip->journal_size;
|
||||
tgt->u.integrity.journal_watermark = ip->journal_watermark;
|
||||
@@ -2920,3 +3133,13 @@ int dm_linear_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t se
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dm_zero_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t seg_size)
|
||||
{
|
||||
tgt->type = DM_ZERO;
|
||||
tgt->direction = TARGET_SET;
|
||||
tgt->offset = seg_offset;
|
||||
tgt->size = seg_size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* loop-AES compatible volume handling
|
||||
*
|
||||
* Copyright (C) 2011-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2011-2019 Milan Broz
|
||||
* Copyright (C) 2011-2021 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2011-2021 Milan Broz
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -81,7 +81,7 @@ static int hash_keys(struct crypt_device *cd,
|
||||
const char *hash_name;
|
||||
char tweak, *key_ptr;
|
||||
unsigned int i;
|
||||
int r;
|
||||
int r = 0;
|
||||
|
||||
hash_name = hash_override ?: get_hash(key_len_output);
|
||||
tweak = get_tweak(keys_count);
|
||||
@@ -242,7 +242,7 @@ int LOOPAES_activate(struct crypt_device *cd,
|
||||
|
||||
if (r < 0 && !dm_flags(cd, DM_CRYPT, &dmc_flags) &&
|
||||
(dmc_flags & req_flags) != req_flags) {
|
||||
log_err(cd, _("Kernel doesn't support loop-AES compatible mapping."));
|
||||
log_err(cd, _("Kernel does not support loop-AES compatible mapping."));
|
||||
r = -ENOTSUP;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* loop-AES compatible volume handling
|
||||
*
|
||||
* Copyright (C) 2011-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2011-2019 Milan Broz
|
||||
* Copyright (C) 2011-2021 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2011-2021 Milan Broz
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* AFsplitter - Anti forensic information splitter
|
||||
*
|
||||
* Copyright (C) 2004 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2021 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* AFsplitter diffuses information over a large stripe of data,
|
||||
* therefore supporting secure data destruction.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* AFsplitter - Anti forensic information splitter
|
||||
*
|
||||
* Copyright (C) 2004 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2021 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* AFsplitter diffuses information over a large stripe of data,
|
||||
* therefore supporting secure data destruction.
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
* LUKS - Linux Unified Key Setup
|
||||
*
|
||||
* Copyright (C) 2004-2006 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2019 Milan Broz
|
||||
* Copyright (C) 2009-2021 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2021 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -22,7 +22,6 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/stat.h>
|
||||
#include "luks.h"
|
||||
@@ -89,7 +88,7 @@ static int LUKS_endec_template(char *src, size_t srcLength,
|
||||
r = device_block_adjust(ctx, crypt_metadata_device(ctx), DEV_OK,
|
||||
sector, &dmd.size, &dmd.flags);
|
||||
if (r < 0) {
|
||||
log_err(ctx, _("Device %s doesn't exist or access denied."),
|
||||
log_err(ctx, _("Device %s does not exist or access denied."),
|
||||
device_path(crypt_metadata_device(ctx)));
|
||||
return -EIO;
|
||||
}
|
||||
@@ -154,7 +153,7 @@ int LUKS_encrypt_to_storage(char *src, size_t srcLength,
|
||||
return -EINVAL;
|
||||
|
||||
/* Encrypt buffer */
|
||||
r = crypt_storage_init(&s, SECTOR_SIZE, cipher, cipher_mode, vk->key, vk->keylength);
|
||||
r = crypt_storage_init(&s, SECTOR_SIZE, cipher, cipher_mode, vk->key, vk->keylength, false);
|
||||
|
||||
if (r)
|
||||
log_dbg(ctx, "Userspace crypto wrapper cannot use %s-%s (%d).",
|
||||
@@ -219,7 +218,7 @@ int LUKS_decrypt_from_storage(char *dst, size_t dstLength,
|
||||
if (MISALIGNED_512(dstLength))
|
||||
return -EINVAL;
|
||||
|
||||
r = crypt_storage_init(&s, SECTOR_SIZE, cipher, cipher_mode, vk->key, vk->keylength);
|
||||
r = crypt_storage_init(&s, SECTOR_SIZE, cipher, cipher_mode, vk->key, vk->keylength, false);
|
||||
|
||||
if (r)
|
||||
log_dbg(ctx, "Userspace crypto wrapper cannot use %s-%s (%d).",
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
* LUKS - Linux Unified Key Setup
|
||||
*
|
||||
* Copyright (C) 2004-2006 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2013-2019 Milan Broz
|
||||
* Copyright (C) 2009-2021 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2013-2021 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -23,7 +23,6 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <netinet/in.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
@@ -260,7 +259,7 @@ int LUKS_hdr_backup(const char *backup_file, struct crypt_device *ctx)
|
||||
|
||||
r = 0;
|
||||
out:
|
||||
crypt_memzero(&hdr, sizeof(hdr));
|
||||
crypt_safe_memzero(&hdr, sizeof(hdr));
|
||||
crypt_safe_free(buffer);
|
||||
return r;
|
||||
}
|
||||
@@ -284,7 +283,7 @@ int LUKS_hdr_restore(
|
||||
buffer_size = LUKS_device_sectors(&hdr_file) << SECTOR_SHIFT;
|
||||
|
||||
if (r || buffer_size < LUKS_ALIGN_KEYSLOTS) {
|
||||
log_err(ctx, _("Backup file doesn't contain valid LUKS header."));
|
||||
log_err(ctx, _("Backup file does not contain valid LUKS header."));
|
||||
r = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
@@ -376,8 +375,13 @@ static int _keyslot_repair(struct luks_phdr *phdr, struct crypt_device *ctx)
|
||||
log_err(ctx, _("Non standard key size, manual repair required."));
|
||||
return -EINVAL;
|
||||
}
|
||||
/* cryptsetup 1.0 did not align to 4k, cannot repair this one */
|
||||
if (LUKS_keyslots_offset(phdr) < (LUKS_ALIGN_KEYSLOTS / SECTOR_SIZE)) {
|
||||
|
||||
/*
|
||||
* cryptsetup 1.0 did not align keyslots to 4k, cannot repair this one
|
||||
* Also we cannot trust possibly broken keyslots metadata here through LUKS_keyslots_offset().
|
||||
* Expect first keyslot is aligned, if not, then manual repair is neccessary.
|
||||
*/
|
||||
if (phdr->keyblock[0].keyMaterialOffset < (LUKS_ALIGN_KEYSLOTS / SECTOR_SIZE)) {
|
||||
log_err(ctx, _("Non standard keyslots alignment, manual repair required."));
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -387,6 +391,8 @@ static int _keyslot_repair(struct luks_phdr *phdr, struct crypt_device *ctx)
|
||||
return -EINVAL;
|
||||
|
||||
vk = crypt_alloc_volume_key(phdr->keyBytes, NULL);
|
||||
if (!vk)
|
||||
return -ENOMEM;
|
||||
|
||||
log_verbose(ctx, _("Repairing keyslots."));
|
||||
|
||||
@@ -453,7 +459,7 @@ out:
|
||||
if (r)
|
||||
log_err(ctx, _("Repair failed."));
|
||||
crypt_free_volume_key(vk);
|
||||
crypt_memzero(&temp_phdr, sizeof(temp_phdr));
|
||||
crypt_safe_memzero(&temp_phdr, sizeof(temp_phdr));
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -692,7 +698,7 @@ int LUKS_check_cipher(struct crypt_device *ctx, size_t keylength, const char *ci
|
||||
r = LUKS_decrypt_from_storage(buf, sizeof(buf), cipher, cipher_mode, empty_key, 0, ctx);
|
||||
|
||||
crypt_free_volume_key(empty_key);
|
||||
crypt_memzero(buf, sizeof(buf));
|
||||
crypt_safe_memzero(buf, sizeof(buf));
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -787,10 +793,15 @@ int LUKS_generate_phdr(struct luks_phdr *header,
|
||||
return r;
|
||||
assert(pbkdf->iterations);
|
||||
|
||||
PBKDF2_temp = (double)pbkdf->iterations * LUKS_MKD_ITERATIONS_MS / pbkdf->time_ms;
|
||||
if (pbkdf->flags & CRYPT_PBKDF_NO_BENCHMARK && pbkdf->time_ms == 0)
|
||||
PBKDF2_temp = LUKS_MKD_ITERATIONS_MIN;
|
||||
else /* iterations per ms * LUKS_MKD_ITERATIONS_MS */
|
||||
PBKDF2_temp = (double)pbkdf->iterations * LUKS_MKD_ITERATIONS_MS / pbkdf->time_ms;
|
||||
|
||||
if (PBKDF2_temp > (double)UINT32_MAX)
|
||||
return -EINVAL;
|
||||
header->mkDigestIterations = at_least((uint32_t)PBKDF2_temp, LUKS_MKD_ITERATIONS_MIN);
|
||||
assert(header->mkDigestIterations);
|
||||
|
||||
r = crypt_pbkdf(CRYPT_KDF_PBKDF2, header->hashSpec, vk->key,vk->keylength,
|
||||
header->mkDigestSalt, LUKS_SALTSIZE,
|
||||
@@ -951,12 +962,12 @@ static int LUKS_open_key(unsigned int keyIndex,
|
||||
const char *password,
|
||||
size_t passwordLen,
|
||||
struct luks_phdr *hdr,
|
||||
struct volume_key *vk,
|
||||
struct volume_key **vk,
|
||||
struct crypt_device *ctx)
|
||||
{
|
||||
crypt_keyslot_info ki = LUKS_keyslot_info(hdr, keyIndex);
|
||||
struct volume_key *derived_key;
|
||||
char *AfKey;
|
||||
char *AfKey = NULL;
|
||||
size_t AFEKSize;
|
||||
int r;
|
||||
|
||||
@@ -970,8 +981,13 @@ static int LUKS_open_key(unsigned int keyIndex,
|
||||
if (!derived_key)
|
||||
return -ENOMEM;
|
||||
|
||||
assert(vk->keylength == hdr->keyBytes);
|
||||
AFEKSize = AF_split_sectors(vk->keylength, hdr->keyblock[keyIndex].stripes) * SECTOR_SIZE;
|
||||
*vk = crypt_alloc_volume_key(hdr->keyBytes, NULL);
|
||||
if (!*vk) {
|
||||
r = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
AFEKSize = AF_split_sectors(hdr->keyBytes, hdr->keyblock[keyIndex].stripes) * SECTOR_SIZE;
|
||||
AfKey = crypt_safe_alloc(AFEKSize);
|
||||
if (!AfKey) {
|
||||
r = -ENOMEM;
|
||||
@@ -982,8 +998,10 @@ static int LUKS_open_key(unsigned int keyIndex,
|
||||
hdr->keyblock[keyIndex].passwordSalt, LUKS_SALTSIZE,
|
||||
derived_key->key, hdr->keyBytes,
|
||||
hdr->keyblock[keyIndex].passwordIterations, 0, 0);
|
||||
if (r < 0)
|
||||
if (r < 0) {
|
||||
log_err(ctx, _("Cannot open keyslot (using hash %s)."), hdr->hashSpec);
|
||||
goto out;
|
||||
}
|
||||
|
||||
log_dbg(ctx, "Reading key slot %d area.", keyIndex);
|
||||
r = LUKS_decrypt_from_storage(AfKey,
|
||||
@@ -995,16 +1013,20 @@ static int LUKS_open_key(unsigned int keyIndex,
|
||||
if (r < 0)
|
||||
goto out;
|
||||
|
||||
r = AF_merge(ctx, AfKey, vk->key, vk->keylength, hdr->keyblock[keyIndex].stripes, hdr->hashSpec);
|
||||
r = AF_merge(ctx, AfKey, (*vk)->key, (*vk)->keylength, hdr->keyblock[keyIndex].stripes, hdr->hashSpec);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
|
||||
r = LUKS_verify_volume_key(hdr, vk);
|
||||
r = LUKS_verify_volume_key(hdr, *vk);
|
||||
|
||||
/* Allow only empty passphrase with null cipher */
|
||||
if (!r && !strcmp(hdr->cipherName, "cipher_null") && passwordLen)
|
||||
if (!r && crypt_is_cipher_null(hdr->cipherName) && passwordLen)
|
||||
r = -EPERM;
|
||||
out:
|
||||
if (r < 0) {
|
||||
crypt_free_volume_key(*vk);
|
||||
*vk = NULL;
|
||||
}
|
||||
crypt_safe_free(AfKey);
|
||||
crypt_free_volume_key(derived_key);
|
||||
return r;
|
||||
@@ -1020,16 +1042,14 @@ int LUKS_open_key_with_hdr(int keyIndex,
|
||||
unsigned int i, tried = 0;
|
||||
int r;
|
||||
|
||||
*vk = crypt_alloc_volume_key(hdr->keyBytes, NULL);
|
||||
|
||||
if (keyIndex >= 0) {
|
||||
r = LUKS_open_key(keyIndex, password, passwordLen, hdr, *vk, ctx);
|
||||
r = LUKS_open_key(keyIndex, password, passwordLen, hdr, vk, ctx);
|
||||
return (r < 0) ? r : keyIndex;
|
||||
}
|
||||
|
||||
for (i = 0; i < LUKS_NUMKEYS; i++) {
|
||||
r = LUKS_open_key(i, password, passwordLen, hdr, *vk, ctx);
|
||||
if(r == 0)
|
||||
r = LUKS_open_key(i, password, passwordLen, hdr, vk, ctx);
|
||||
if (r == 0)
|
||||
return i;
|
||||
|
||||
/* Do not retry for errors that are no -EPERM or -ENOENT,
|
||||
@@ -1224,7 +1244,7 @@ int LUKS_wipe_header_areas(struct luks_phdr *hdr,
|
||||
|
||||
int LUKS_keyslot_pbkdf(struct luks_phdr *hdr, int keyslot, struct crypt_pbkdf_type *pbkdf)
|
||||
{
|
||||
if (keyslot >= LUKS_NUMKEYS || keyslot < 0)
|
||||
if (LUKS_keyslot_info(hdr, keyslot) < CRYPT_SLOT_ACTIVE)
|
||||
return -EINVAL;
|
||||
|
||||
pbkdf->type = CRYPT_KDF_PBKDF2;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* LUKS - Linux Unified Key Setup
|
||||
*
|
||||
* Copyright (C) 2004-2006 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2021 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* LUKS - Linux Unified Key Setup v2
|
||||
*
|
||||
* Copyright (C) 2015-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2019 Milan Broz
|
||||
* Copyright (C) 2015-2021 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2021 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -23,6 +23,8 @@
|
||||
#define _CRYPTSETUP_LUKS2_ONDISK_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "libcryptsetup.h"
|
||||
|
||||
@@ -330,6 +332,12 @@ int LUKS2_token_is_assigned(struct crypt_device *cd,
|
||||
int keyslot,
|
||||
int token);
|
||||
|
||||
int LUKS2_token_assignment_copy(struct crypt_device *cd,
|
||||
struct luks2_hdr *hdr,
|
||||
int keyslot_from,
|
||||
int keyslot_to,
|
||||
int commit);
|
||||
|
||||
int LUKS2_token_create(struct crypt_device *cd,
|
||||
struct luks2_hdr *hdr,
|
||||
int token,
|
||||
@@ -523,7 +531,7 @@ int LUKS2_check_metadata_area_size(uint64_t metadata_size);
|
||||
int LUKS2_check_keyslots_area_size(uint64_t keyslots_size);
|
||||
|
||||
int LUKS2_wipe_header_areas(struct crypt_device *cd,
|
||||
struct luks2_hdr *hdr);
|
||||
struct luks2_hdr *hdr, bool detached_header);
|
||||
|
||||
uint64_t LUKS2_get_data_offset(struct luks2_hdr *hdr);
|
||||
int LUKS2_get_data_size(struct luks2_hdr *hdr, uint64_t *size, bool *dynamic);
|
||||
@@ -600,7 +608,8 @@ int LUKS2_assembly_multisegment_dmd(struct crypt_device *cd,
|
||||
crypt_reencrypt_info LUKS2_reencrypt_status(struct crypt_device *cd,
|
||||
struct crypt_params_reencrypt *params);
|
||||
|
||||
int crypt_reencrypt_lock(struct crypt_device *cd, const char *uuid, struct crypt_lock_handle **reencrypt_lock);
|
||||
int crypt_reencrypt_lock(struct crypt_device *cd, struct crypt_lock_handle **reencrypt_lock);
|
||||
int crypt_reencrypt_lock_by_dm_uuid(struct crypt_device *cd, const char *dm_uuid, struct crypt_lock_handle **reencrypt_lock);
|
||||
void crypt_reencrypt_unlock(struct crypt_device *cd, struct crypt_lock_handle *reencrypt_lock);
|
||||
|
||||
int luks2_check_device_size(struct crypt_device *cd, struct luks2_hdr *hdr, uint64_t check_size, uint64_t *dev_size, bool activation, bool dynamic);
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* LUKS - Linux Unified Key Setup v2, digest handling
|
||||
*
|
||||
* Copyright (C) 2015-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2019 Milan Broz
|
||||
* Copyright (C) 2015-2021 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2021 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* LUKS - Linux Unified Key Setup v2, PBKDF2 digest handler (LUKS1 compatible)
|
||||
*
|
||||
* Copyright (C) 2015-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2019 Milan Broz
|
||||
* Copyright (C) 2015-2021 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2021 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* LUKS - Linux Unified Key Setup v2
|
||||
*
|
||||
* Copyright (C) 2015-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2019 Milan Broz
|
||||
* Copyright (C) 2015-2021 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2021 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -175,13 +175,13 @@ static void hdr_to_disk(struct luks2_hdr *hdr,
|
||||
hdr_disk->hdr_offset = cpu_to_be64(offset);
|
||||
hdr_disk->seqid = cpu_to_be64(hdr->seqid);
|
||||
|
||||
strncpy(hdr_disk->label, hdr->label, LUKS2_LABEL_L);
|
||||
memcpy(hdr_disk->label, hdr->label, MIN(strlen(hdr->label), LUKS2_LABEL_L));
|
||||
hdr_disk->label[LUKS2_LABEL_L - 1] = '\0';
|
||||
strncpy(hdr_disk->subsystem, hdr->subsystem, LUKS2_LABEL_L);
|
||||
memcpy(hdr_disk->subsystem, hdr->subsystem, MIN(strlen(hdr->subsystem), LUKS2_LABEL_L));
|
||||
hdr_disk->subsystem[LUKS2_LABEL_L - 1] = '\0';
|
||||
strncpy(hdr_disk->checksum_alg, hdr->checksum_alg, LUKS2_CHECKSUM_ALG_L);
|
||||
memcpy(hdr_disk->checksum_alg, hdr->checksum_alg, MIN(strlen(hdr->checksum_alg), LUKS2_CHECKSUM_ALG_L));
|
||||
hdr_disk->checksum_alg[LUKS2_CHECKSUM_ALG_L - 1] = '\0';
|
||||
strncpy(hdr_disk->uuid, hdr->uuid, LUKS2_UUID_L);
|
||||
memcpy(hdr_disk->uuid, hdr->uuid, MIN(strlen(hdr->uuid), LUKS2_UUID_L));
|
||||
hdr_disk->uuid[LUKS2_UUID_L - 1] = '\0';
|
||||
|
||||
memcpy(hdr_disk->salt, secondary ? hdr->salt2 : hdr->salt1, LUKS2_SALT_L);
|
||||
@@ -210,7 +210,7 @@ static int hdr_disk_sanity_check_pre(struct crypt_device *cd,
|
||||
}
|
||||
|
||||
if (secondary && (offset != be64_to_cpu(hdr->hdr_size))) {
|
||||
log_dbg(cd, "LUKS2 offset 0x%04x in secondary header doesn't match size 0x%04x.",
|
||||
log_dbg(cd, "LUKS2 offset 0x%04x in secondary header does not match size 0x%04x.",
|
||||
(unsigned)offset, (unsigned)be64_to_cpu(hdr->hdr_size));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* LUKS - Linux Unified Key Setup v2
|
||||
*
|
||||
* Copyright (C) 2015-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2019 Milan Broz
|
||||
* Copyright (C) 2015-2021 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2021 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -23,7 +23,6 @@
|
||||
#define _CRYPTSETUP_LUKS2_INTERNAL_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <json-c/json.h>
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* LUKS - Linux Unified Key Setup v2, LUKS2 header format code
|
||||
*
|
||||
* Copyright (C) 2015-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2019 Milan Broz
|
||||
* Copyright (C) 2015-2021 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2021 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -244,7 +244,8 @@ int LUKS2_generate_hdr(
|
||||
/* Decrease keyslots_size due to metadata device being too small */
|
||||
if (!device_size(crypt_metadata_device(cd), &mdev_size) &&
|
||||
((keyslots_size + get_min_offset(hdr)) > mdev_size) &&
|
||||
device_fallocate(crypt_metadata_device(cd), keyslots_size + get_min_offset(hdr)))
|
||||
device_fallocate(crypt_metadata_device(cd), keyslots_size + get_min_offset(hdr)) &&
|
||||
(get_min_offset(hdr) <= mdev_size))
|
||||
keyslots_size = mdev_size - get_min_offset(hdr);
|
||||
}
|
||||
|
||||
@@ -337,7 +338,7 @@ err:
|
||||
}
|
||||
|
||||
int LUKS2_wipe_header_areas(struct crypt_device *cd,
|
||||
struct luks2_hdr *hdr)
|
||||
struct luks2_hdr *hdr, bool detached_header)
|
||||
{
|
||||
int r;
|
||||
uint64_t offset, length;
|
||||
@@ -352,7 +353,7 @@ int LUKS2_wipe_header_areas(struct crypt_device *cd,
|
||||
return -EINVAL;
|
||||
|
||||
/* On detached header wipe at least the first 4k */
|
||||
if (length == 0) {
|
||||
if (detached_header) {
|
||||
length = 4096;
|
||||
wipe_block = 4096;
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
/*
|
||||
* LUKS - Linux Unified Key Setup v2
|
||||
*
|
||||
* Copyright (C) 2015-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2019 Milan Broz
|
||||
* Copyright (C) 2015-2019 Ondrej Kozina
|
||||
* Copyright (C) 2015-2021 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2021 Milan Broz
|
||||
* Copyright (C) 2015-2021 Ondrej Kozina
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -45,11 +45,11 @@ void hexprint_base64(struct crypt_device *cd, json_object *jobj,
|
||||
&buf, &buf_len))
|
||||
return;
|
||||
|
||||
for (i = 0; i < buf_len / 2; i++)
|
||||
log_std(cd, "%02hhx%s", buf[i], sep);
|
||||
log_std(cd, "\n\t%s", line_sep);
|
||||
for (i = buf_len / 2; i < buf_len; i++)
|
||||
for (i = 0; i < buf_len; i++) {
|
||||
if (i && !(i % 16))
|
||||
log_std(cd, "\n\t%s", line_sep);
|
||||
log_std(cd, "%02hhx%s", buf[i], sep);
|
||||
}
|
||||
log_std(cd, "\n");
|
||||
free(buf);
|
||||
}
|
||||
@@ -459,12 +459,12 @@ static int hdr_validate_json_size(struct crypt_device *cd, json_object *hdr_jobj
|
||||
json_size = (uint64_t)strlen(json);
|
||||
|
||||
if (hdr_json_size != json_area_size) {
|
||||
log_dbg(cd, "JSON area size doesn't match value in binary header.");
|
||||
log_dbg(cd, "JSON area size does not match value in binary header.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (json_size > json_area_size) {
|
||||
log_dbg(cd, "JSON doesn't fit in the designated area.");
|
||||
log_dbg(cd, "JSON does not fit in the designated area.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -594,9 +594,9 @@ static bool validate_segment_intervals(struct crypt_device *cd,
|
||||
static int hdr_validate_segments(struct crypt_device *cd, json_object *hdr_jobj)
|
||||
{
|
||||
json_object *jobj_segments, *jobj_digests, *jobj_offset, *jobj_size, *jobj_type, *jobj_flags, *jobj;
|
||||
struct interval *intervals;
|
||||
uint64_t offset, size;
|
||||
int i, r, count, first_backup = -1;
|
||||
struct interval *intervals = NULL;
|
||||
|
||||
if (!json_object_object_get_ex(hdr_jobj, "segments", &jobj_segments)) {
|
||||
log_dbg(cd, "Missing segments section.");
|
||||
@@ -676,10 +676,18 @@ static int hdr_validate_segments(struct crypt_device *cd, json_object *hdr_jobj)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* avoid needlessly large allocation when first backup segment is invalid */
|
||||
if (first_backup >= count) {
|
||||
log_dbg(cd, "Gap between last regular segment and backup segment at key %d.", first_backup);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (first_backup < 0)
|
||||
first_backup = count;
|
||||
|
||||
intervals = malloc(first_backup * sizeof(*intervals));
|
||||
if ((size_t)first_backup < SIZE_MAX / sizeof(*intervals))
|
||||
intervals = malloc(first_backup * sizeof(*intervals));
|
||||
|
||||
if (!intervals) {
|
||||
log_dbg(cd, "Not enough memory.");
|
||||
return 1;
|
||||
@@ -970,13 +978,16 @@ int LUKS2_hdr_read(struct crypt_device *cd, struct luks2_hdr *hdr, int repair)
|
||||
return r;
|
||||
}
|
||||
|
||||
int LUKS2_hdr_write_force(struct crypt_device *cd, struct luks2_hdr *hdr)
|
||||
static int hdr_cleanup_and_validate(struct crypt_device *cd, struct luks2_hdr *hdr)
|
||||
{
|
||||
/* NOTE: is called before LUKS2 validation routines */
|
||||
/* erase unused digests (no assigned keyslot or segment) */
|
||||
LUKS2_digests_erase_unused(cd, hdr);
|
||||
|
||||
if (LUKS2_hdr_validate(cd, hdr->jobj, hdr->hdr_size - LUKS2_HDR_BIN_LEN))
|
||||
return LUKS2_hdr_validate(cd, hdr->jobj, hdr->hdr_size - LUKS2_HDR_BIN_LEN);
|
||||
}
|
||||
|
||||
int LUKS2_hdr_write_force(struct crypt_device *cd, struct luks2_hdr *hdr)
|
||||
{
|
||||
if (hdr_cleanup_and_validate(cd, hdr))
|
||||
return -EINVAL;
|
||||
|
||||
return LUKS2_disk_hdr_write(cd, hdr, crypt_metadata_device(cd), false);
|
||||
@@ -984,11 +995,7 @@ int LUKS2_hdr_write_force(struct crypt_device *cd, struct luks2_hdr *hdr)
|
||||
|
||||
int LUKS2_hdr_write(struct crypt_device *cd, struct luks2_hdr *hdr)
|
||||
{
|
||||
/* NOTE: is called before LUKS2 validation routines */
|
||||
/* erase unused digests (no assigned keyslot or segment) */
|
||||
LUKS2_digests_erase_unused(cd, hdr);
|
||||
|
||||
if (LUKS2_hdr_validate(cd, hdr->jobj, hdr->hdr_size - LUKS2_HDR_BIN_LEN))
|
||||
if (hdr_cleanup_and_validate(cd, hdr))
|
||||
return -EINVAL;
|
||||
|
||||
return LUKS2_disk_hdr_write(cd, hdr, crypt_metadata_device(cd), true);
|
||||
@@ -1159,7 +1166,7 @@ int LUKS2_hdr_restore(struct crypt_device *cd, struct luks2_hdr *hdr,
|
||||
device_free(cd, backup_device);
|
||||
|
||||
if (r < 0) {
|
||||
log_err(cd, _("Backup file doesn't contain valid LUKS header."));
|
||||
log_err(cd, _("Backup file does not contain valid LUKS header."));
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -1270,8 +1277,8 @@ out:
|
||||
LUKS2_hdr_free(cd, hdr);
|
||||
LUKS2_hdr_free(cd, &hdr_file);
|
||||
LUKS2_hdr_free(cd, &tmp_hdr);
|
||||
crypt_memzero(&hdr_file, sizeof(hdr_file));
|
||||
crypt_memzero(&tmp_hdr, sizeof(tmp_hdr));
|
||||
crypt_safe_memzero(&hdr_file, sizeof(hdr_file));
|
||||
crypt_safe_memzero(&tmp_hdr, sizeof(tmp_hdr));
|
||||
crypt_safe_free(buffer);
|
||||
|
||||
device_sync(cd, device);
|
||||
@@ -1290,6 +1297,8 @@ static const struct {
|
||||
{ CRYPT_ACTIVATE_SAME_CPU_CRYPT, "same-cpu-crypt" },
|
||||
{ CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS, "submit-from-crypt-cpus" },
|
||||
{ CRYPT_ACTIVATE_NO_JOURNAL, "no-journal" },
|
||||
{ CRYPT_ACTIVATE_NO_READ_WORKQUEUE, "no-read-workqueue" },
|
||||
{ CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE, "no-write-workqueue" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
@@ -2157,7 +2166,12 @@ int LUKS2_activate(struct crypt_device *cd,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
r = INTEGRITY_create_dmd_device(cd, NULL, NULL, NULL, NULL, &dmdi, dmd.flags);
|
||||
if (dmd.flags & CRYPT_ACTIVATE_ALLOW_DISCARDS) {
|
||||
log_err(cd, _("Discard/TRIM is not supported."));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
r = INTEGRITY_create_dmd_device(cd, NULL, NULL, NULL, NULL, &dmdi, dmd.flags, 0);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
@@ -2205,26 +2219,21 @@ int LUKS2_deactivate(struct crypt_device *cd, const char *name, struct luks2_hdr
|
||||
struct dm_target *tgt;
|
||||
crypt_status_info ci;
|
||||
struct crypt_dm_active_device dmdc;
|
||||
char **dep, uuid[37], deps_uuid_prefix[40], *deps[MAX_DM_DEPS+1] = { 0 };
|
||||
char **dep, deps_uuid_prefix[40], *deps[MAX_DM_DEPS+1] = { 0 };
|
||||
const char *namei = NULL;
|
||||
struct crypt_lock_handle *reencrypt_lock = NULL;
|
||||
|
||||
if (!dmd || !dmd->uuid)
|
||||
if (!dmd || !dmd->uuid || strncmp(CRYPT_LUKS2, dmd->uuid, sizeof(CRYPT_LUKS2)-1))
|
||||
return -EINVAL;
|
||||
|
||||
/* uuid mismatch with metadata (if available) */
|
||||
if (hdr && crypt_uuid_cmp(dmd->uuid, hdr->uuid))
|
||||
return -EINVAL;
|
||||
|
||||
r = snprintf(deps_uuid_prefix, sizeof(deps_uuid_prefix), CRYPT_SUBDEV "-%.32s", dmd->uuid + 6);
|
||||
if (r < 0 || (size_t)r != (sizeof(deps_uuid_prefix) - 1))
|
||||
return -EINVAL;
|
||||
|
||||
r = snprintf(uuid, sizeof(uuid), "%.8s-%.4s-%.4s-%.4s-%.12s",
|
||||
dmd->uuid + 6, dmd->uuid + 14, dmd->uuid + 18, dmd->uuid + 22, dmd->uuid + 26);
|
||||
if (r < 0 || (size_t)r != (sizeof(uuid) - 1))
|
||||
return -EINVAL;
|
||||
|
||||
/* uuid mismatch with metadata (if available) */
|
||||
if (hdr && strcmp(hdr->uuid, uuid))
|
||||
return -EINVAL;
|
||||
|
||||
tgt = &dmd->segment;
|
||||
|
||||
/* TODO: We have LUKS2 dependencies now */
|
||||
@@ -2236,7 +2245,7 @@ int LUKS2_deactivate(struct crypt_device *cd, const char *name, struct luks2_hdr
|
||||
goto out;
|
||||
|
||||
if (contains_reencryption_helper(deps)) {
|
||||
r = crypt_reencrypt_lock(cd, uuid, &reencrypt_lock);
|
||||
r = crypt_reencrypt_lock_by_dm_uuid(cd, dmd->uuid, &reencrypt_lock);
|
||||
if (r) {
|
||||
if (r == -EBUSY)
|
||||
log_err(cd, _("Reencryption in-progress. Cannot deactivate device."));
|
||||
@@ -2345,9 +2354,9 @@ int LUKS2_unmet_requirements(struct crypt_device *cd, struct luks2_hdr *hdr, uin
|
||||
reqs &= ~reqs_mask;
|
||||
|
||||
if (reqs_reencrypt(reqs) && !quiet)
|
||||
log_err(cd, _("Offline reencryption in progress. Aborting."));
|
||||
log_err(cd, _("Operation incompatible with device marked for legacy reencryption. Aborting."));
|
||||
if (reqs_reencrypt_online(reqs) && !quiet)
|
||||
log_err(cd, _("Online reencryption in progress. Aborting."));
|
||||
log_err(cd, _("Operation incompatible with device marked for LUKS2 reencryption. Aborting."));
|
||||
|
||||
/* any remaining unmasked requirement fails the check */
|
||||
return reqs ? -EINVAL : 0;
|
||||
@@ -2400,7 +2409,7 @@ int json_object_object_add_by_uint(json_object *jobj, unsigned key, json_object
|
||||
#endif
|
||||
}
|
||||
|
||||
/* jobj_dst must contain pointer initialised to NULL (see json-c json_object_deep_copy API) */
|
||||
/* jobj_dst must contain pointer initialized to NULL (see json-c json_object_deep_copy API) */
|
||||
int json_object_copy(json_object *jobj_src, json_object **jobj_dst)
|
||||
{
|
||||
if (!jobj_src || !jobj_dst || *jobj_dst)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* LUKS - Linux Unified Key Setup v2, keyslot handling
|
||||
*
|
||||
* Copyright (C) 2015-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2019 Milan Broz
|
||||
* Copyright (C) 2015-2021 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2021 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -27,9 +27,7 @@ extern const keyslot_handler reenc_keyslot;
|
||||
|
||||
static const keyslot_handler *keyslot_handlers[LUKS2_KEYSLOTS_MAX] = {
|
||||
&luks2_keyslot,
|
||||
#if USE_LUKS2_REENCRYPTION
|
||||
&reenc_keyslot,
|
||||
#endif
|
||||
NULL
|
||||
};
|
||||
|
||||
@@ -81,19 +79,18 @@ int LUKS2_keyslot_find_empty(struct luks2_hdr *hdr)
|
||||
/* Check if a keyslot is assigned to specific segment */
|
||||
static int _keyslot_for_segment(struct luks2_hdr *hdr, int keyslot, int segment)
|
||||
{
|
||||
int keyslot_digest, segment_digest, s, count = 0;
|
||||
int keyslot_digest, count = 0;
|
||||
unsigned s;
|
||||
|
||||
keyslot_digest = LUKS2_digest_by_keyslot(hdr, keyslot);
|
||||
if (keyslot_digest < 0)
|
||||
return keyslot_digest;
|
||||
|
||||
if (segment >= 0) {
|
||||
segment_digest = LUKS2_digest_by_segment(hdr, segment);
|
||||
return segment_digest == keyslot_digest;
|
||||
}
|
||||
for (s = 0; s < 3; s++) {
|
||||
segment_digest = LUKS2_digest_by_segment(hdr, s);
|
||||
if (segment_digest == keyslot_digest)
|
||||
if (segment >= 0)
|
||||
return keyslot_digest == LUKS2_digest_by_segment(hdr, segment);
|
||||
|
||||
for (s = 0; s < json_segments_count(LUKS2_get_segments_jobj(hdr)); s++) {
|
||||
if (keyslot_digest == LUKS2_digest_by_segment(hdr, s))
|
||||
count++;
|
||||
}
|
||||
|
||||
@@ -151,7 +148,7 @@ int LUKS2_keyslot_cipher_incompatible(struct crypt_device *cd, const char *ciphe
|
||||
{
|
||||
char cipher[MAX_CIPHER_LEN], cipher_mode[MAX_CIPHER_LEN];
|
||||
|
||||
if (!cipher_spec || !strcmp(cipher_spec, "null") || !strcmp(cipher_spec, "cipher_null"))
|
||||
if (!cipher_spec || crypt_is_cipher_null(cipher_spec))
|
||||
return 1;
|
||||
|
||||
if (crypt_parse_name_and_mode(cipher_spec, cipher, NULL, cipher_mode) < 0)
|
||||
@@ -312,28 +309,16 @@ int LUKS2_keyslot_area(struct luks2_hdr *hdr,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int LUKS2_open_and_verify_by_digest(struct crypt_device *cd,
|
||||
static int _open_and_verify(struct crypt_device *cd,
|
||||
struct luks2_hdr *hdr,
|
||||
const keyslot_handler *h,
|
||||
int keyslot,
|
||||
int digest,
|
||||
const char *password,
|
||||
size_t password_len,
|
||||
struct volume_key **vk)
|
||||
{
|
||||
const keyslot_handler *h;
|
||||
int key_size, r;
|
||||
int r, key_size = LUKS2_get_keyslot_stored_key_size(hdr, keyslot);
|
||||
|
||||
if (!(h = LUKS2_keyslot_handler(cd, keyslot)))
|
||||
return -ENOENT;
|
||||
|
||||
r = _keyslot_for_digest(hdr, keyslot, digest);
|
||||
if (r) {
|
||||
if (r == -ENOENT)
|
||||
log_dbg(cd, "Keyslot %d unusable for digest %d.", keyslot, digest);
|
||||
return r;
|
||||
}
|
||||
|
||||
key_size = LUKS2_get_keyslot_stored_key_size(hdr, keyslot);
|
||||
if (key_size < 0)
|
||||
return -EINVAL;
|
||||
|
||||
@@ -352,9 +337,41 @@ static int LUKS2_open_and_verify_by_digest(struct crypt_device *cd,
|
||||
*vk = NULL;
|
||||
}
|
||||
|
||||
crypt_volume_key_set_id(*vk, r);
|
||||
|
||||
return r < 0 ? r : keyslot;
|
||||
}
|
||||
|
||||
static int LUKS2_open_and_verify_by_digest(struct crypt_device *cd,
|
||||
struct luks2_hdr *hdr,
|
||||
int keyslot,
|
||||
int digest,
|
||||
const char *password,
|
||||
size_t password_len,
|
||||
struct volume_key **vk)
|
||||
{
|
||||
const keyslot_handler *h;
|
||||
int r;
|
||||
|
||||
if (!(h = LUKS2_keyslot_handler(cd, keyslot)))
|
||||
return -ENOENT;
|
||||
|
||||
r = h->validate(cd, LUKS2_get_keyslot_jobj(hdr, keyslot));
|
||||
if (r) {
|
||||
log_dbg(cd, "Keyslot %d validation failed.", keyslot);
|
||||
return r;
|
||||
}
|
||||
|
||||
r = _keyslot_for_digest(hdr, keyslot, digest);
|
||||
if (r) {
|
||||
if (r == -ENOENT)
|
||||
log_dbg(cd, "Keyslot %d unusable for digest %d.", keyslot, digest);
|
||||
return r;
|
||||
}
|
||||
|
||||
return _open_and_verify(cd, hdr, h, keyslot, password, password_len, vk);
|
||||
}
|
||||
|
||||
static int LUKS2_open_and_verify(struct crypt_device *cd,
|
||||
struct luks2_hdr *hdr,
|
||||
int keyslot,
|
||||
@@ -364,7 +381,7 @@ static int LUKS2_open_and_verify(struct crypt_device *cd,
|
||||
struct volume_key **vk)
|
||||
{
|
||||
const keyslot_handler *h;
|
||||
int key_size, r;
|
||||
int r;
|
||||
|
||||
if (!(h = LUKS2_keyslot_handler(cd, keyslot)))
|
||||
return -ENOENT;
|
||||
@@ -382,29 +399,7 @@ static int LUKS2_open_and_verify(struct crypt_device *cd,
|
||||
return r;
|
||||
}
|
||||
|
||||
key_size = LUKS2_get_volume_key_size(hdr, segment);
|
||||
if (key_size < 0)
|
||||
key_size = LUKS2_get_keyslot_stored_key_size(hdr, keyslot);
|
||||
if (key_size < 0)
|
||||
return -EINVAL;
|
||||
|
||||
*vk = crypt_alloc_volume_key(key_size, NULL);
|
||||
if (!*vk)
|
||||
return -ENOMEM;
|
||||
|
||||
r = h->open(cd, keyslot, password, password_len, (*vk)->key, (*vk)->keylength);
|
||||
if (r < 0)
|
||||
log_dbg(cd, "Keyslot %d (%s) open failed with %d.", keyslot, h->name, r);
|
||||
else
|
||||
r = LUKS2_digest_verify(cd, hdr, *vk, keyslot);
|
||||
|
||||
if (r < 0) {
|
||||
crypt_free_volume_key(*vk);
|
||||
*vk = NULL;
|
||||
} else
|
||||
crypt_volume_key_set_id(*vk, r);
|
||||
|
||||
return r < 0 ? r : keyslot;
|
||||
return _open_and_verify(cd, hdr, h, keyslot, password, password_len, vk);
|
||||
}
|
||||
|
||||
static int LUKS2_keyslot_open_priority_digest(struct crypt_device *cd,
|
||||
@@ -522,7 +517,7 @@ int LUKS2_keyslot_open_all_segments(struct crypt_device *cd,
|
||||
size_t password_len,
|
||||
struct volume_key **vks)
|
||||
{
|
||||
struct volume_key *vk;
|
||||
struct volume_key *vk = NULL;
|
||||
int digest_old, digest_new, r = -EINVAL;
|
||||
struct luks2_hdr *hdr = crypt_get_hdr(cd, CRYPT_LUKS2);
|
||||
|
||||
@@ -532,7 +527,6 @@ int LUKS2_keyslot_open_all_segments(struct crypt_device *cd,
|
||||
r = LUKS2_keyslot_open_by_digest(cd, hdr, keyslot_old, digest_old, password, password_len, &vk);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
crypt_volume_key_set_id(vk, digest_old);
|
||||
crypt_volume_key_add_next(vks, vk);
|
||||
}
|
||||
|
||||
@@ -542,7 +536,6 @@ int LUKS2_keyslot_open_all_segments(struct crypt_device *cd,
|
||||
r = LUKS2_keyslot_open_by_digest(cd, hdr, keyslot_new, digest_new, password, password_len, &vk);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
crypt_volume_key_set_id(vk, digest_new);
|
||||
crypt_volume_key_add_next(vks, vk);
|
||||
}
|
||||
out:
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* LUKS - Linux Unified Key Setup v2, LUKS2 type keyslot handler
|
||||
*
|
||||
* Copyright (C) 2015-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2019 Milan Broz
|
||||
* Copyright (C) 2015-2021 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2021 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -48,7 +48,7 @@ static int luks2_encrypt_to_storage(char *src, size_t srcLength,
|
||||
return -EINVAL;
|
||||
|
||||
/* Encrypt buffer */
|
||||
r = crypt_storage_init(&s, SECTOR_SIZE, cipher, cipher_mode, vk->key, vk->keylength);
|
||||
r = crypt_storage_init(&s, SECTOR_SIZE, cipher, cipher_mode, vk->key, vk->keylength, false);
|
||||
if (r) {
|
||||
log_err(cd, _("Cannot use %s-%s cipher for keyslot encryption."), cipher, cipher_mode);
|
||||
return r;
|
||||
@@ -103,7 +103,7 @@ static int luks2_decrypt_from_storage(char *dst, size_t dstLength,
|
||||
if (MISALIGNED_512(dstLength))
|
||||
return -EINVAL;
|
||||
|
||||
r = crypt_storage_init(&s, SECTOR_SIZE, cipher, cipher_mode, vk->key, vk->keylength);
|
||||
r = crypt_storage_init(&s, SECTOR_SIZE, cipher, cipher_mode, vk->key, vk->keylength, false);
|
||||
if (r) {
|
||||
log_err(cd, _("Cannot use %s-%s cipher for keyslot encryption."), cipher, cipher_mode);
|
||||
return r;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* LUKS - Linux Unified Key Setup v2, reencryption keyslot handler
|
||||
*
|
||||
* Copyright (C) 2016-2018, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2016-2018, Ondrej Kozina
|
||||
* Copyright (C) 2016-2021, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2016-2021, Ondrej Kozina
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
/*
|
||||
* LUKS - Linux Unified Key Setup v2, LUKS1 conversion code
|
||||
*
|
||||
* Copyright (C) 2015-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2019 Ondrej Kozina
|
||||
* Copyright (C) 2015-2019 Milan Broz
|
||||
* Copyright (C) 2015-2021 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2021 Ondrej Kozina
|
||||
* Copyright (C) 2015-2021 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -467,7 +467,7 @@ static int move_keyslot_areas(struct crypt_device *cd, off_t offset_from,
|
||||
r = 0;
|
||||
out:
|
||||
device_sync(cd, device);
|
||||
crypt_memzero(buf, buf_size);
|
||||
crypt_safe_memzero(buf, buf_size);
|
||||
free(buf);
|
||||
|
||||
return r;
|
||||
@@ -578,6 +578,12 @@ int LUKS2_luks1_to_luks2(struct crypt_device *cd, struct luks_phdr *hdr1, struct
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* check future LUKS2 metadata before moving keyslots area */
|
||||
if (LUKS2_hdr_validate(cd, hdr2->jobj, hdr2->hdr_size - LUKS2_HDR_BIN_LEN)) {
|
||||
r = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ((r = luks_header_in_use(cd))) {
|
||||
if (r > 0)
|
||||
r = -EBUSY;
|
||||
@@ -669,7 +675,7 @@ static int keyslot_LUKS1_compatible(struct crypt_device *cd, struct luks2_hdr *h
|
||||
int LUKS2_luks2_to_luks1(struct crypt_device *cd, struct luks2_hdr *hdr2, struct luks_phdr *hdr1)
|
||||
{
|
||||
size_t buf_size, buf_offset;
|
||||
char cipher[LUKS_CIPHERNAME_L-1], cipher_mode[LUKS_CIPHERMODE_L-1];
|
||||
char cipher[LUKS_CIPHERNAME_L], cipher_mode[LUKS_CIPHERMODE_L];
|
||||
char digest[LUKS_DIGESTSIZE], digest_salt[LUKS_SALTSIZE];
|
||||
const char *hash;
|
||||
size_t len;
|
||||
@@ -818,8 +824,10 @@ int LUKS2_luks2_to_luks1(struct crypt_device *cd, struct luks2_hdr *hdr2, struct
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
strncpy(hdr1->cipherName, cipher, sizeof(hdr1->cipherName) - 1);
|
||||
strncpy(hdr1->cipherMode, cipher_mode, sizeof(hdr1->cipherMode) - 1);
|
||||
strncpy(hdr1->cipherName, cipher, LUKS_CIPHERNAME_L - 1);
|
||||
hdr1->cipherName[LUKS_CIPHERNAME_L-1] = '\0';
|
||||
strncpy(hdr1->cipherMode, cipher_mode, LUKS_CIPHERMODE_L - 1);
|
||||
hdr1->cipherMode[LUKS_CIPHERMODE_L-1] = '\0';
|
||||
|
||||
if (!json_object_object_get_ex(jobj_keyslot, "kdf", &jobj_kdf))
|
||||
return -EINVAL;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* LUKS - Linux Unified Key Setup v2, reencryption helpers
|
||||
*
|
||||
* Copyright (C) 2015-2019, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2019, Ondrej Kozina
|
||||
* Copyright (C) 2015-2021, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2021, Ondrej Kozina
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -22,7 +22,6 @@
|
||||
#include "luks2_internal.h"
|
||||
#include "utils_device_locking.h"
|
||||
|
||||
#if USE_LUKS2_REENCRYPTION
|
||||
static json_object *reencrypt_segment(struct luks2_hdr *hdr, unsigned new)
|
||||
{
|
||||
return LUKS2_get_segment_by_flag(hdr, new ? "backup-final" : "backup-previous");
|
||||
@@ -86,7 +85,7 @@ static uint64_t reencrypt_get_data_offset_old(struct luks2_hdr *hdr)
|
||||
{
|
||||
return reencrypt_data_offset(hdr, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int reencrypt_digest(struct luks2_hdr *hdr, unsigned new)
|
||||
{
|
||||
int segment = LUKS2_get_segment_id_by_flag(hdr, new ? "backup-final" : "backup-previous");
|
||||
@@ -145,7 +144,7 @@ static const char *reencrypt_resilience_hash(struct luks2_hdr *hdr)
|
||||
|
||||
return json_object_get_string(jobj_hash);
|
||||
}
|
||||
#if USE_LUKS2_REENCRYPTION
|
||||
|
||||
static uint32_t reencrypt_alignment(struct luks2_hdr *hdr)
|
||||
{
|
||||
json_object *jobj_keyslot, *jobj_area, *jobj_type, *jobj_hash, *jobj_sector_size;
|
||||
@@ -561,7 +560,7 @@ static int reencrypt_make_post_segments(struct crypt_device *cd,
|
||||
|
||||
return rh->jobj_segs_post ? 0 : -EINVAL;
|
||||
}
|
||||
#endif
|
||||
|
||||
static uint64_t reencrypt_data_shift(struct luks2_hdr *hdr)
|
||||
{
|
||||
json_object *jobj_keyslot, *jobj_area, *jobj_data_shift;
|
||||
@@ -667,7 +666,7 @@ void LUKS2_reenc_context_free(struct crypt_device *cd, struct luks2_reenc_contex
|
||||
crypt_unlock_internal(cd, rh->reenc_lock);
|
||||
free(rh);
|
||||
}
|
||||
#if USE_LUKS2_REENCRYPTION
|
||||
|
||||
static size_t reencrypt_get_alignment(struct crypt_device *cd,
|
||||
struct luks2_hdr *hdr)
|
||||
{
|
||||
@@ -1402,12 +1401,12 @@ static int reencrypt_recover_segment(struct crypt_device *cd,
|
||||
log_dbg(cd, "Failed to read journaled data.");
|
||||
r = -EIO;
|
||||
/* may content plaintext */
|
||||
crypt_memzero(data_buffer, rh->length);
|
||||
crypt_safe_memzero(data_buffer, rh->length);
|
||||
goto out;
|
||||
}
|
||||
read = crypt_storage_wrapper_encrypt_write(cw2, 0, data_buffer, rh->length);
|
||||
/* may content plaintext */
|
||||
crypt_memzero(data_buffer, rh->length);
|
||||
crypt_safe_memzero(data_buffer, rh->length);
|
||||
if (read < 0 || (size_t)read != rh->length) {
|
||||
log_dbg(cd, "recovery write failed.");
|
||||
r = -EINVAL;
|
||||
@@ -1437,13 +1436,13 @@ static int reencrypt_recover_segment(struct crypt_device *cd,
|
||||
log_dbg(cd, "Failed to read data.");
|
||||
r = -EIO;
|
||||
/* may content plaintext */
|
||||
crypt_memzero(data_buffer, rh->length);
|
||||
crypt_safe_memzero(data_buffer, rh->length);
|
||||
goto out;
|
||||
}
|
||||
|
||||
read = crypt_storage_wrapper_encrypt_write(cw2, 0, data_buffer, rh->length);
|
||||
/* may content plaintext */
|
||||
crypt_memzero(data_buffer, rh->length);
|
||||
crypt_safe_memzero(data_buffer, rh->length);
|
||||
if (read < 0 || (size_t)read != rh->length) {
|
||||
log_dbg(cd, "recovery write failed.");
|
||||
r = -EINVAL;
|
||||
@@ -2239,7 +2238,7 @@ static int reencrypt_verify_and_upload_keys(struct crypt_device *cd, struct luks
|
||||
if (LUKS2_digest_verify_by_digest(cd, hdr, digest_new, vk) != digest_new)
|
||||
return -EINVAL;
|
||||
|
||||
if (crypt_use_keyring_for_vk(cd) &&
|
||||
if (crypt_use_keyring_for_vk(cd) && !crypt_is_cipher_null(reencrypt_segment_cipher_new(hdr)) &&
|
||||
(r = LUKS2_volume_key_load_in_keyring_by_digest(cd, hdr, vk, crypt_volume_key_get_id(vk))))
|
||||
return r;
|
||||
}
|
||||
@@ -2255,7 +2254,7 @@ static int reencrypt_verify_and_upload_keys(struct crypt_device *cd, struct luks
|
||||
r = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
if (crypt_use_keyring_for_vk(cd) &&
|
||||
if (crypt_use_keyring_for_vk(cd) && !crypt_is_cipher_null(reencrypt_segment_cipher_old(hdr)) &&
|
||||
(r = LUKS2_volume_key_load_in_keyring_by_digest(cd, hdr, vk, crypt_volume_key_get_id(vk))))
|
||||
goto err;
|
||||
}
|
||||
@@ -2532,7 +2531,7 @@ static int reencrypt_load(struct crypt_device *cd, struct luks2_hdr *hdr,
|
||||
else if (ri == CRYPT_REENCRYPT_CRASH)
|
||||
r = reencrypt_load_crashed(cd, hdr, device_size, &tmp);
|
||||
else if (ri == CRYPT_REENCRYPT_NONE) {
|
||||
log_err(cd, _("No LUKS2 reencryption in progress."));
|
||||
log_err(cd, _("Device not marked for LUKS2 reencryption."));
|
||||
return -EINVAL;
|
||||
} else
|
||||
r = -EINVAL;
|
||||
@@ -2546,22 +2545,11 @@ static int reencrypt_load(struct crypt_device *cd, struct luks2_hdr *hdr,
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
/* internal only */
|
||||
int crypt_reencrypt_lock(struct crypt_device *cd, const char *uuid, struct crypt_lock_handle **reencrypt_lock)
|
||||
|
||||
static int reencrypt_lock_internal(struct crypt_device *cd, const char *uuid, struct crypt_lock_handle **reencrypt_lock)
|
||||
{
|
||||
int r;
|
||||
char *lock_resource;
|
||||
const char *tmp = crypt_get_uuid(cd);
|
||||
|
||||
if (!tmp && !uuid)
|
||||
return -EINVAL;
|
||||
if (!uuid)
|
||||
uuid = tmp;
|
||||
if (!tmp)
|
||||
tmp = uuid;
|
||||
if (strcmp(uuid, tmp))
|
||||
return -EINVAL;
|
||||
|
||||
if (!crypt_metadata_locking_enabled()) {
|
||||
*reencrypt_lock = NULL;
|
||||
@@ -2583,12 +2571,42 @@ out:
|
||||
return r;
|
||||
}
|
||||
|
||||
/* internal only */
|
||||
int crypt_reencrypt_lock_by_dm_uuid(struct crypt_device *cd, const char *dm_uuid, struct crypt_lock_handle **reencrypt_lock)
|
||||
{
|
||||
int r;
|
||||
char hdr_uuid[37];
|
||||
const char *uuid = crypt_get_uuid(cd);
|
||||
|
||||
if (!dm_uuid)
|
||||
return -EINVAL;
|
||||
|
||||
if (!uuid) {
|
||||
r = snprintf(hdr_uuid, sizeof(hdr_uuid), "%.8s-%.4s-%.4s-%.4s-%.12s",
|
||||
dm_uuid + 6, dm_uuid + 14, dm_uuid + 18, dm_uuid + 22, dm_uuid + 26);
|
||||
if (r < 0 || (size_t)r != (sizeof(hdr_uuid) - 1))
|
||||
return -EINVAL;
|
||||
} else if (crypt_uuid_cmp(dm_uuid, uuid))
|
||||
return -EINVAL;
|
||||
|
||||
return reencrypt_lock_internal(cd, uuid, reencrypt_lock);
|
||||
}
|
||||
|
||||
/* internal only */
|
||||
int crypt_reencrypt_lock(struct crypt_device *cd, struct crypt_lock_handle **reencrypt_lock)
|
||||
{
|
||||
if (!cd || !crypt_get_type(cd) || strcmp(crypt_get_type(cd), CRYPT_LUKS2))
|
||||
return -EINVAL;
|
||||
|
||||
return reencrypt_lock_internal(cd, crypt_get_uuid(cd), reencrypt_lock);
|
||||
}
|
||||
|
||||
/* internal only */
|
||||
void crypt_reencrypt_unlock(struct crypt_device *cd, struct crypt_lock_handle *reencrypt_lock)
|
||||
{
|
||||
crypt_unlock_internal(cd, reencrypt_lock);
|
||||
}
|
||||
#if USE_LUKS2_REENCRYPTION
|
||||
|
||||
static int reencrypt_lock_and_verify(struct crypt_device *cd, struct luks2_hdr *hdr,
|
||||
struct crypt_lock_handle **reencrypt_lock)
|
||||
{
|
||||
@@ -2606,7 +2624,7 @@ static int reencrypt_lock_and_verify(struct crypt_device *cd, struct luks2_hdr *
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
r = crypt_reencrypt_lock(cd, NULL, &h);
|
||||
r = crypt_reencrypt_lock(cd, &h);
|
||||
if (r < 0) {
|
||||
if (r == -EBUSY)
|
||||
log_err(cd, _("Reencryption process is already running."));
|
||||
@@ -2646,6 +2664,7 @@ static int reencrypt_load_by_passphrase(struct crypt_device *cd,
|
||||
struct luks2_hdr *hdr;
|
||||
struct crypt_lock_handle *reencrypt_lock;
|
||||
struct luks2_reenc_context *rh;
|
||||
const struct volume_key *vk;
|
||||
struct crypt_dm_active_device dmd_target, dmd_source = {
|
||||
.uuid = crypt_get_uuid(cd),
|
||||
.flags = CRYPT_ACTIVATE_SHARED /* turn off exclusive open checks */
|
||||
@@ -2712,6 +2731,19 @@ static int reencrypt_load_by_passphrase(struct crypt_device *cd,
|
||||
goto err;
|
||||
flags = dmd_target.flags;
|
||||
|
||||
/*
|
||||
* By default reencryption code aims to retain flags from existing dm device.
|
||||
* The keyring activation flag can not be inherited if original cipher is null.
|
||||
*
|
||||
* In this case override the flag based on decision made in reencrypt_verify_and_upload_keys
|
||||
* above. The code checks if new VK is eligible for keyring.
|
||||
*/
|
||||
vk = crypt_volume_key_by_id(*vks, LUKS2_reencrypt_digest_new(hdr));
|
||||
if (vk && vk->key_description && crypt_is_cipher_null(reencrypt_segment_cipher_old(hdr))) {
|
||||
flags |= CRYPT_ACTIVATE_KEYRING_KEY;
|
||||
dmd_source.flags |= CRYPT_ACTIVATE_KEYRING_KEY;
|
||||
}
|
||||
|
||||
r = LUKS2_assembly_multisegment_dmd(cd, hdr, *vks, LUKS2_get_segments_jobj(hdr), &dmd_source);
|
||||
if (!r) {
|
||||
r = crypt_compare_dm_devices(cd, &dmd_source, &dmd_target);
|
||||
@@ -2810,7 +2842,7 @@ static int reencrypt_recovery_by_passphrase(struct crypt_device *cd,
|
||||
crypt_reencrypt_info ri;
|
||||
struct crypt_lock_handle *reencrypt_lock;
|
||||
|
||||
r = crypt_reencrypt_lock(cd, NULL, &reencrypt_lock);
|
||||
r = crypt_reencrypt_lock(cd, &reencrypt_lock);
|
||||
if (r) {
|
||||
if (r == -EBUSY)
|
||||
log_err(cd, _("Reencryption in-progress. Cannot perform recovery."));
|
||||
@@ -2843,7 +2875,7 @@ static int reencrypt_recovery_by_passphrase(struct crypt_device *cd,
|
||||
crypt_reencrypt_unlock(cd, reencrypt_lock);
|
||||
return r;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int reencrypt_init_by_passphrase(struct crypt_device *cd,
|
||||
const char *name,
|
||||
const char *passphrase,
|
||||
@@ -2854,7 +2886,6 @@ static int reencrypt_init_by_passphrase(struct crypt_device *cd,
|
||||
const char *cipher_mode,
|
||||
const struct crypt_params_reencrypt *params)
|
||||
{
|
||||
#if USE_LUKS2_REENCRYPTION
|
||||
int r;
|
||||
crypt_reencrypt_info ri;
|
||||
struct volume_key *vks = NULL;
|
||||
@@ -2865,7 +2896,7 @@ static int reencrypt_init_by_passphrase(struct crypt_device *cd,
|
||||
if (flags & CRYPT_REENCRYPT_RECOVERY)
|
||||
return reencrypt_recovery_by_passphrase(cd, hdr, keyslot_old, keyslot_new, passphrase, passphrase_size);
|
||||
|
||||
if (cipher) {
|
||||
if (cipher && !crypt_cipher_wrapped_key(cipher, cipher_mode)) {
|
||||
r = crypt_keyslot_get_key_size(cd, keyslot_new);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@@ -2910,10 +2941,6 @@ out:
|
||||
crypt_drop_keyring_key(cd, vks);
|
||||
crypt_free_volume_key(vks);
|
||||
return r < 0 ? r : LUKS2_find_keyslot(hdr, "reencrypt");
|
||||
#else
|
||||
log_err(cd, _("This operation is not supported for this device type."));
|
||||
return -ENOTSUP;
|
||||
#endif
|
||||
}
|
||||
|
||||
int crypt_reencrypt_init_by_keyring(struct crypt_device *cd,
|
||||
@@ -2942,7 +2969,7 @@ int crypt_reencrypt_init_by_keyring(struct crypt_device *cd,
|
||||
|
||||
r = reencrypt_init_by_passphrase(cd, name, passphrase, passphrase_size, keyslot_old, keyslot_new, cipher, cipher_mode, params);
|
||||
|
||||
crypt_memzero(passphrase, passphrase_size);
|
||||
crypt_safe_memzero(passphrase, passphrase_size);
|
||||
free(passphrase);
|
||||
|
||||
return r;
|
||||
@@ -2966,7 +2993,6 @@ int crypt_reencrypt_init_by_passphrase(struct crypt_device *cd,
|
||||
return reencrypt_init_by_passphrase(cd, name, passphrase, passphrase_size, keyslot_old, keyslot_new, cipher, cipher_mode, params);
|
||||
}
|
||||
|
||||
#if USE_LUKS2_REENCRYPTION
|
||||
static reenc_status_t reencrypt_step(struct crypt_device *cd,
|
||||
struct luks2_hdr *hdr,
|
||||
struct luks2_reenc_context *rh,
|
||||
@@ -3207,11 +3233,10 @@ static int reencrypt_teardown(struct crypt_device *cd, struct luks2_hdr *hdr,
|
||||
|
||||
return r;
|
||||
}
|
||||
#endif
|
||||
|
||||
int crypt_reencrypt(struct crypt_device *cd,
|
||||
int (*progress)(uint64_t size, uint64_t offset, void *usrptr))
|
||||
{
|
||||
#if USE_LUKS2_REENCRYPTION
|
||||
int r;
|
||||
crypt_reencrypt_info ri;
|
||||
struct luks2_hdr *hdr;
|
||||
@@ -3269,12 +3294,8 @@ int crypt_reencrypt(struct crypt_device *cd,
|
||||
|
||||
r = reencrypt_teardown(cd, hdr, rh, rs, quit, progress);
|
||||
return r;
|
||||
#else
|
||||
log_err(cd, _("This operation is not supported for this device type."));
|
||||
return -ENOTSUP;
|
||||
#endif
|
||||
}
|
||||
#if USE_LUKS2_REENCRYPTION
|
||||
|
||||
static int reencrypt_recovery(struct crypt_device *cd,
|
||||
struct luks2_hdr *hdr,
|
||||
uint64_t device_size,
|
||||
@@ -3310,7 +3331,7 @@ err:
|
||||
|
||||
return r;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* use only for calculation of minimal data device size.
|
||||
* The real data offset is taken directly from segments!
|
||||
@@ -3325,7 +3346,7 @@ int LUKS2_reencrypt_data_offset(struct luks2_hdr *hdr, bool blockwise)
|
||||
|
||||
return blockwise ? data_offset : data_offset << SECTOR_SHIFT;
|
||||
}
|
||||
#if USE_LUKS2_REENCRYPTION
|
||||
|
||||
/* internal only */
|
||||
int luks2_check_device_size(struct crypt_device *cd, struct luks2_hdr *hdr, uint64_t check_size, uint64_t *dev_size, bool activation, bool dynamic)
|
||||
{
|
||||
@@ -3398,7 +3419,7 @@ int LUKS2_reencrypt_locked_recovery_by_passphrase(struct crypt_device *cd,
|
||||
r = LUKS2_volume_key_load_in_keyring_by_digest(cd, hdr, vk, crypt_volume_key_get_id(vk));
|
||||
if (r < 0)
|
||||
goto err;
|
||||
vk = vk->next;
|
||||
vk = crypt_volume_key_next(vk);
|
||||
}
|
||||
|
||||
if (luks2_check_device_size(cd, hdr, minimal_size, &device_size, true, false))
|
||||
@@ -3415,7 +3436,7 @@ err:
|
||||
|
||||
return r < 0 ? r : keyslot;
|
||||
}
|
||||
#endif
|
||||
|
||||
crypt_reencrypt_info LUKS2_reencrypt_status(struct crypt_device *cd, struct crypt_params_reencrypt *params)
|
||||
{
|
||||
crypt_reencrypt_info ri;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* LUKS - Linux Unified Key Setup v2, internal segment handling
|
||||
*
|
||||
* Copyright (C) 2018-2019, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2018-2019, Ondrej Kozina
|
||||
* Copyright (C) 2018-2021, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2018-2021, Ondrej Kozina
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* LUKS - Linux Unified Key Setup v2, token handling
|
||||
*
|
||||
* Copyright (C) 2016-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2016-2019 Milan Broz
|
||||
* Copyright (C) 2016-2021 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2016-2021 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -329,10 +329,10 @@ static void LUKS2_token_buffer_free(struct crypt_device *cd,
|
||||
{
|
||||
const crypt_token_handler *h = LUKS2_token_handler(cd, token);
|
||||
|
||||
if (h->buffer_free)
|
||||
if (h && h->buffer_free)
|
||||
h->buffer_free(buffer, buffer_len);
|
||||
else {
|
||||
crypt_memzero(buffer, buffer_len);
|
||||
crypt_safe_memzero(buffer, buffer_len);
|
||||
free(buffer);
|
||||
}
|
||||
}
|
||||
@@ -383,6 +383,7 @@ int LUKS2_token_open_and_activate(struct crypt_device *cd,
|
||||
uint32_t flags,
|
||||
void *usrptr)
|
||||
{
|
||||
bool use_keyring;
|
||||
int keyslot, r;
|
||||
char *buffer;
|
||||
size_t buffer_len;
|
||||
@@ -404,7 +405,13 @@ int LUKS2_token_open_and_activate(struct crypt_device *cd,
|
||||
|
||||
keyslot = r;
|
||||
|
||||
if ((name || (flags & CRYPT_ACTIVATE_KEYRING_KEY)) && crypt_use_keyring_for_vk(cd)) {
|
||||
if (!crypt_use_keyring_for_vk(cd))
|
||||
use_keyring = false;
|
||||
else
|
||||
use_keyring = ((name && !crypt_is_cipher_null(crypt_get_cipher(cd))) ||
|
||||
(flags & CRYPT_ACTIVATE_KEYRING_KEY));
|
||||
|
||||
if (use_keyring) {
|
||||
if (!(r = LUKS2_volume_key_load_in_keyring_by_keyslot(cd, hdr, vk, keyslot)))
|
||||
flags |= CRYPT_ACTIVATE_KEYRING_KEY;
|
||||
}
|
||||
@@ -576,16 +583,12 @@ int LUKS2_token_assign(struct crypt_device *cd, struct luks2_hdr *hdr,
|
||||
return token;
|
||||
}
|
||||
|
||||
int LUKS2_token_is_assigned(struct crypt_device *cd, struct luks2_hdr *hdr,
|
||||
int keyslot, int token)
|
||||
static int token_is_assigned(struct luks2_hdr *hdr, int keyslot, int token)
|
||||
{
|
||||
int i;
|
||||
json_object *jobj_token, *jobj_token_keyslots, *jobj;
|
||||
json_object *jobj, *jobj_token_keyslots,
|
||||
*jobj_token = LUKS2_get_token_jobj(hdr, token);
|
||||
|
||||
if (keyslot < 0 || keyslot >= LUKS2_KEYSLOTS_MAX || token < 0 || token >= LUKS2_TOKENS_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
jobj_token = LUKS2_get_token_jobj(hdr, token);
|
||||
if (!jobj_token)
|
||||
return -ENOENT;
|
||||
|
||||
@@ -600,6 +603,15 @@ int LUKS2_token_is_assigned(struct crypt_device *cd, struct luks2_hdr *hdr,
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
int LUKS2_token_is_assigned(struct crypt_device *cd, struct luks2_hdr *hdr,
|
||||
int keyslot, int token)
|
||||
{
|
||||
if (keyslot < 0 || keyslot >= LUKS2_KEYSLOTS_MAX || token < 0 || token >= LUKS2_TOKENS_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
return token_is_assigned(hdr, keyslot, token);
|
||||
}
|
||||
|
||||
int LUKS2_tokens_count(struct luks2_hdr *hdr)
|
||||
{
|
||||
json_object *jobj_tokens = LUKS2_get_tokens_jobj(hdr);
|
||||
@@ -608,3 +620,28 @@ int LUKS2_tokens_count(struct luks2_hdr *hdr)
|
||||
|
||||
return json_object_object_length(jobj_tokens);
|
||||
}
|
||||
|
||||
int LUKS2_token_assignment_copy(struct crypt_device *cd,
|
||||
struct luks2_hdr *hdr,
|
||||
int keyslot_from,
|
||||
int keyslot_to,
|
||||
int commit)
|
||||
{
|
||||
int i, r;
|
||||
|
||||
if (keyslot_from < 0 || keyslot_from >= LUKS2_KEYSLOTS_MAX || keyslot_to < 0 || keyslot_to >= LUKS2_KEYSLOTS_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
r = LUKS2_tokens_count(hdr);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
for (i = 0; i < LUKS2_TOKENS_MAX; i++) {
|
||||
if (!token_is_assigned(hdr, keyslot_from, i)) {
|
||||
if ((r = assign_one_token(cd, hdr, keyslot_to, i, 1)))
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
return commit ? LUKS2_hdr_write(cd, hdr) : 0;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* LUKS - Linux Unified Key Setup v2, kernel keyring token
|
||||
*
|
||||
* Copyright (C) 2016-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2016-2019 Ondrej Kozina
|
||||
* Copyright (C) 2016-2021 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2016-2021 Ondrej Kozina
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* cryptsetup kernel RNG access functions
|
||||
*
|
||||
* Copyright (C) 2010-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2021 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -20,7 +20,6 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <sys/select.h>
|
||||
@@ -28,10 +27,6 @@
|
||||
#include "libcryptsetup.h"
|
||||
#include "internal.h"
|
||||
|
||||
#ifndef O_CLOEXEC
|
||||
#define O_CLOEXEC 0
|
||||
#endif
|
||||
|
||||
static int random_initialised = 0;
|
||||
|
||||
#define URANDOM_DEVICE "/dev/urandom"
|
||||
|
||||
582
lib/setup.c
582
lib/setup.c
File diff suppressed because it is too large
Load Diff
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* TCRYPT (TrueCrypt-compatible) and VeraCrypt volume handling
|
||||
*
|
||||
* Copyright (C) 2012-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2019 Milan Broz
|
||||
* Copyright (C) 2012-2021 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2021 Milan Broz
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -23,7 +23,6 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "libcryptsetup.h"
|
||||
@@ -301,8 +300,8 @@ static int decrypt_blowfish_le_cbc(struct tcrypt_alg *alg,
|
||||
}
|
||||
|
||||
crypt_cipher_destroy(cipher);
|
||||
crypt_memzero(iv, bs);
|
||||
crypt_memzero(iv_old, bs);
|
||||
crypt_safe_memzero(iv, bs);
|
||||
crypt_safe_memzero(iv_old, bs);
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -369,8 +368,8 @@ static int TCRYPT_decrypt_hdr_one(struct tcrypt_alg *alg, const char *mode,
|
||||
crypt_cipher_destroy(cipher);
|
||||
}
|
||||
|
||||
crypt_memzero(backend_key, sizeof(backend_key));
|
||||
crypt_memzero(iv, TCRYPT_HDR_IV_LEN);
|
||||
crypt_safe_memzero(backend_key, sizeof(backend_key));
|
||||
crypt_safe_memzero(iv, TCRYPT_HDR_IV_LEN);
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -420,8 +419,8 @@ out:
|
||||
if (cipher[j])
|
||||
crypt_cipher_destroy(cipher[j]);
|
||||
|
||||
crypt_memzero(iv, bs);
|
||||
crypt_memzero(iv_old, bs);
|
||||
crypt_safe_memzero(iv, bs);
|
||||
crypt_safe_memzero(iv_old, bs);
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -474,13 +473,13 @@ static int TCRYPT_decrypt_hdr(struct crypt_device *cd, struct tcrypt_phdr *hdr,
|
||||
r = -EPERM;
|
||||
}
|
||||
|
||||
crypt_memzero(&hdr2, sizeof(hdr2));
|
||||
crypt_safe_memzero(&hdr2, sizeof(hdr2));
|
||||
return r;
|
||||
}
|
||||
|
||||
static int TCRYPT_pool_keyfile(struct crypt_device *cd,
|
||||
unsigned char pool[TCRYPT_KEY_POOL_LEN],
|
||||
const char *keyfile)
|
||||
unsigned char pool[VCRYPT_KEY_POOL_LEN],
|
||||
const char *keyfile, int keyfiles_pool_length)
|
||||
{
|
||||
unsigned char *data;
|
||||
int i, j, fd, data_size, r = -EIO;
|
||||
@@ -512,12 +511,12 @@ static int TCRYPT_pool_keyfile(struct crypt_device *cd,
|
||||
pool[j++] += (unsigned char)(crc >> 16);
|
||||
pool[j++] += (unsigned char)(crc >> 8);
|
||||
pool[j++] += (unsigned char)(crc);
|
||||
j %= TCRYPT_KEY_POOL_LEN;
|
||||
j %= keyfiles_pool_length;
|
||||
}
|
||||
r = 0;
|
||||
out:
|
||||
crypt_memzero(&crc, sizeof(crc));
|
||||
crypt_memzero(data, TCRYPT_KEYFILE_LEN);
|
||||
crypt_safe_memzero(&crc, sizeof(crc));
|
||||
crypt_safe_memzero(data, TCRYPT_KEYFILE_LEN);
|
||||
free(data);
|
||||
|
||||
return r;
|
||||
@@ -527,29 +526,39 @@ static int TCRYPT_init_hdr(struct crypt_device *cd,
|
||||
struct tcrypt_phdr *hdr,
|
||||
struct crypt_params_tcrypt *params)
|
||||
{
|
||||
unsigned char pwd[TCRYPT_KEY_POOL_LEN] = {};
|
||||
size_t passphrase_size;
|
||||
unsigned char pwd[VCRYPT_KEY_POOL_LEN] = {};
|
||||
size_t passphrase_size, max_passphrase_size;
|
||||
char *key;
|
||||
unsigned int i, skipped = 0, iterations;
|
||||
int r = -EPERM;
|
||||
int r = -EPERM, keyfiles_pool_length;
|
||||
|
||||
if (posix_memalign((void*)&key, crypt_getpagesize(), TCRYPT_HDR_KEY_LEN))
|
||||
return -ENOMEM;
|
||||
|
||||
if (params->flags & CRYPT_TCRYPT_VERA_MODES &&
|
||||
params->passphrase_size > TCRYPT_KEY_POOL_LEN) {
|
||||
/* Really. Keyfile pool length depends on passphrase size in Veracrypt. */
|
||||
max_passphrase_size = VCRYPT_KEY_POOL_LEN;
|
||||
keyfiles_pool_length = VCRYPT_KEY_POOL_LEN;
|
||||
} else {
|
||||
max_passphrase_size = TCRYPT_KEY_POOL_LEN;
|
||||
keyfiles_pool_length = TCRYPT_KEY_POOL_LEN;
|
||||
}
|
||||
|
||||
if (params->keyfiles_count)
|
||||
passphrase_size = TCRYPT_KEY_POOL_LEN;
|
||||
passphrase_size = max_passphrase_size;
|
||||
else
|
||||
passphrase_size = params->passphrase_size;
|
||||
|
||||
if (params->passphrase_size > TCRYPT_KEY_POOL_LEN) {
|
||||
log_err(cd, _("Maximum TCRYPT passphrase length (%d) exceeded."),
|
||||
TCRYPT_KEY_POOL_LEN);
|
||||
if (params->passphrase_size > max_passphrase_size) {
|
||||
log_err(cd, _("Maximum TCRYPT passphrase length (%zu) exceeded."),
|
||||
max_passphrase_size);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Calculate pool content from keyfiles */
|
||||
for (i = 0; i < params->keyfiles_count; i++) {
|
||||
r = TCRYPT_pool_keyfile(cd, pwd, params->keyfiles[i]);
|
||||
r = TCRYPT_pool_keyfile(cd, pwd, params->keyfiles[i], keyfiles_pool_length);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
}
|
||||
@@ -619,9 +628,9 @@ static int TCRYPT_init_hdr(struct crypt_device *cd,
|
||||
params->cipher, params->mode, params->key_size);
|
||||
}
|
||||
out:
|
||||
crypt_memzero(pwd, TCRYPT_KEY_POOL_LEN);
|
||||
crypt_safe_memzero(pwd, TCRYPT_KEY_POOL_LEN);
|
||||
if (key)
|
||||
crypt_memzero(key, TCRYPT_HDR_KEY_LEN);
|
||||
crypt_safe_memzero(key, TCRYPT_HDR_KEY_LEN);
|
||||
free(key);
|
||||
return r;
|
||||
}
|
||||
@@ -740,14 +749,14 @@ int TCRYPT_activate(struct crypt_device *cd,
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
if (hdr->d.sector_size && hdr->d.sector_size != SECTOR_SIZE) {
|
||||
if (hdr->d.sector_size % SECTOR_SIZE) {
|
||||
log_err(cd, _("Activation is not supported for %d sector size."),
|
||||
hdr->d.sector_size);
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
if (strstr(params->mode, "-tcrypt")) {
|
||||
log_err(cd, _("Kernel doesn't support activation for this TCRYPT legacy mode."));
|
||||
log_err(cd, _("Kernel does not support activation for this TCRYPT legacy mode."));
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
@@ -760,15 +769,12 @@ int TCRYPT_activate(struct crypt_device *cd,
|
||||
if (!algs)
|
||||
return -EINVAL;
|
||||
|
||||
if (hdr->d.sector_size == 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (params->flags & CRYPT_TCRYPT_SYSTEM_HEADER)
|
||||
dmd.size = 0;
|
||||
else if (params->flags & CRYPT_TCRYPT_HIDDEN_HEADER)
|
||||
dmd.size = hdr->d.hidden_volume_size / hdr->d.sector_size;
|
||||
dmd.size = hdr->d.hidden_volume_size / SECTOR_SIZE;
|
||||
else
|
||||
dmd.size = hdr->d.volume_size / hdr->d.sector_size;
|
||||
dmd.size = hdr->d.volume_size / SECTOR_SIZE;
|
||||
|
||||
if (dmd.flags & CRYPT_ACTIVATE_SHARED)
|
||||
device_check = DEV_OK;
|
||||
@@ -859,7 +865,7 @@ int TCRYPT_activate(struct crypt_device *cd,
|
||||
|
||||
if (r < 0 &&
|
||||
(dm_flags(cd, DM_CRYPT, &dmc_flags) || ((dmc_flags & req_flags) != req_flags))) {
|
||||
log_err(cd, _("Kernel doesn't support TCRYPT compatible mapping."));
|
||||
log_err(cd, _("Kernel does not support TCRYPT compatible mapping."));
|
||||
r = -ENOTSUP;
|
||||
}
|
||||
|
||||
@@ -1033,11 +1039,11 @@ uint64_t TCRYPT_get_data_offset(struct crypt_device *cd,
|
||||
|
||||
if (params->flags & CRYPT_TCRYPT_HIDDEN_HEADER) {
|
||||
if (hdr->d.version > 3)
|
||||
return (hdr->d.mk_offset / hdr->d.sector_size);
|
||||
return (hdr->d.mk_offset / SECTOR_SIZE);
|
||||
if (device_size(crypt_metadata_device(cd), &size) < 0)
|
||||
return 0;
|
||||
return (size - hdr->d.hidden_volume_size +
|
||||
(TCRYPT_HDR_HIDDEN_OFFSET_OLD)) / hdr->d.sector_size;
|
||||
(TCRYPT_HDR_HIDDEN_OFFSET_OLD)) / SECTOR_SIZE;
|
||||
}
|
||||
goto hdr_offset;
|
||||
}
|
||||
@@ -1046,11 +1052,11 @@ uint64_t TCRYPT_get_data_offset(struct crypt_device *cd,
|
||||
if (device_size(crypt_metadata_device(cd), &size) < 0)
|
||||
return 0;
|
||||
return (size - hdr->d.hidden_volume_size +
|
||||
(TCRYPT_HDR_HIDDEN_OFFSET_OLD)) / hdr->d.sector_size;
|
||||
(TCRYPT_HDR_HIDDEN_OFFSET_OLD)) / SECTOR_SIZE;
|
||||
}
|
||||
|
||||
hdr_offset:
|
||||
return hdr->d.mk_offset / hdr->d.sector_size;
|
||||
return hdr->d.mk_offset / SECTOR_SIZE;
|
||||
}
|
||||
|
||||
uint64_t TCRYPT_get_iv_offset(struct crypt_device *cd,
|
||||
@@ -1064,7 +1070,7 @@ uint64_t TCRYPT_get_iv_offset(struct crypt_device *cd,
|
||||
else if (params->mode && !strncmp(params->mode, "lrw", 3))
|
||||
iv_offset = 0;
|
||||
else
|
||||
iv_offset = hdr->d.mk_offset / hdr->d.sector_size;
|
||||
iv_offset = hdr->d.mk_offset / SECTOR_SIZE;
|
||||
|
||||
if (params->flags & CRYPT_TCRYPT_SYSTEM_HEADER)
|
||||
iv_offset += crypt_dev_partition_offset(device_path(crypt_metadata_device(cd)));
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* TCRYPT (TrueCrypt-compatible) header definition
|
||||
*
|
||||
* Copyright (C) 2012-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2019 Milan Broz
|
||||
* Copyright (C) 2012-2021 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2021 Milan Broz
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -42,6 +42,7 @@
|
||||
|
||||
#define TCRYPT_LRW_IKEY_LEN 16
|
||||
#define TCRYPT_KEY_POOL_LEN 64
|
||||
#define VCRYPT_KEY_POOL_LEN 128
|
||||
#define TCRYPT_KEYFILE_LEN 1048576
|
||||
|
||||
#define TCRYPT_HDR_FLAG_SYSTEM (1 << 0)
|
||||
|
||||
11
lib/utils.c
11
lib/utils.c
@@ -3,8 +3,8 @@
|
||||
*
|
||||
* Copyright (C) 2004 Jana Saout <jana@saout.de>
|
||||
* Copyright (C) 2004-2007 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2019 Milan Broz
|
||||
* Copyright (C) 2009-2021 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2021 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -23,7 +23,6 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/stat.h>
|
||||
@@ -130,7 +129,7 @@ static int keyfile_seek(int fd, uint64_t bytes)
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
|
||||
crypt_memzero(tmp, sizeof(tmp));
|
||||
crypt_safe_memzero(tmp, sizeof(tmp));
|
||||
/* read error */
|
||||
return -1;
|
||||
}
|
||||
@@ -142,7 +141,7 @@ static int keyfile_seek(int fd, uint64_t bytes)
|
||||
bytes -= bytes_r;
|
||||
}
|
||||
|
||||
crypt_memzero(tmp, sizeof(tmp));
|
||||
crypt_safe_memzero(tmp, sizeof(tmp));
|
||||
return bytes == 0 ? 0 : -1;
|
||||
}
|
||||
|
||||
@@ -181,7 +180,7 @@ int crypt_keyfile_device_read(struct crypt_device *cd, const char *keyfile,
|
||||
key_size = DEFAULT_KEYFILE_SIZE_MAXKB * 1024 + 1;
|
||||
unlimited_read = 1;
|
||||
/* use 4k for buffer (page divisor but avoid huge pages) */
|
||||
buflen = 4096 - sizeof(struct safe_allocation);
|
||||
buflen = 4096 - sizeof(size_t); // sizeof(struct safe_allocation);
|
||||
} else
|
||||
buflen = key_size;
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* libcryptsetup - cryptsetup library, cipher benchmark
|
||||
*
|
||||
* Copyright (C) 2012-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2019 Milan Broz
|
||||
* Copyright (C) 2012-2021 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2021 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -48,6 +48,12 @@ int crypt_benchmark(struct crypt_device *cd,
|
||||
if (posix_memalign(&buffer, crypt_getpagesize(), buffer_size))
|
||||
goto out;
|
||||
|
||||
r = crypt_cipher_ivsize(cipher, cipher_mode);
|
||||
if (r >= 0 && iv_size != (size_t)r) {
|
||||
log_dbg(cd, "IV length for benchmark adjusted to %i bytes (requested %zu).", r, iv_size);
|
||||
iv_size = r;
|
||||
}
|
||||
|
||||
if (iv_size) {
|
||||
iv = malloc(iv_size);
|
||||
if (!iv)
|
||||
@@ -71,9 +77,9 @@ int crypt_benchmark(struct crypt_device *cd,
|
||||
|
||||
if (r == -ERANGE)
|
||||
log_dbg(cd, "Measured cipher runtime is too low.");
|
||||
else if (r == -ENOTSUP || r == -ENOENT)
|
||||
log_dbg(cd, "Cannot initialise cipher %s, mode %s.", cipher, cipher_mode);
|
||||
|
||||
else if (r)
|
||||
log_dbg(cd, "Cannot initialize cipher %s, mode %s, key size %zu, IV size %zu.",
|
||||
cipher, cipher_mode, volume_key_size, iv_size);
|
||||
out:
|
||||
free(buffer);
|
||||
free(key);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* blkid probe utilities
|
||||
*
|
||||
* Copyright (C) 2018-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2018-2021 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -310,9 +310,9 @@ int blk_supported(void)
|
||||
|
||||
off_t blk_get_offset(struct blkid_handle *h)
|
||||
{
|
||||
const char *offset;
|
||||
off_t offset_value = -1;
|
||||
#ifdef HAVE_BLKID
|
||||
const char *offset;
|
||||
if (blk_is_superblock(h)) {
|
||||
if (!blkid_probe_lookup_value(h->pr, "SBMAGIC_OFFSET", &offset, NULL))
|
||||
offset_value = strtoll(offset, NULL, 10);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* blkid probe utilities
|
||||
*
|
||||
* Copyright (C) 2018-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2018-2021 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -21,6 +21,8 @@
|
||||
#ifndef _UTILS_BLKID_H
|
||||
#define _UTILS_BLKID_H
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
struct blkid_handle;
|
||||
|
||||
typedef enum { PRB_OK = 0, PRB_EMPTY, PRB_AMBIGUOUS, PRB_FAIL } blk_probe_status;
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
* utils_crypt - cipher utilities for cryptsetup
|
||||
*
|
||||
* Copyright (C) 2004-2007 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2019 Milan Broz
|
||||
* Copyright (C) 2009-2021 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2021 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "libcryptsetup.h"
|
||||
@@ -76,8 +77,10 @@ int crypt_parse_hash_integrity_mode(const char *s, char *integrity)
|
||||
return -EINVAL;
|
||||
|
||||
r = sscanf(s, "%" MAX_CIPHER_LEN_STR "[^-]-%" MAX_CIPHER_LEN_STR "s", mode, hash);
|
||||
if (r == 2)
|
||||
if (r == 2 && !isdigit(hash[0]))
|
||||
r = snprintf(integrity, MAX_CIPHER_LEN, "%s(%s)", mode, hash);
|
||||
else if (r == 2)
|
||||
r = snprintf(integrity, MAX_CIPHER_LEN, "%s-%s", mode, hash);
|
||||
else if (r == 1)
|
||||
r = snprintf(integrity, MAX_CIPHER_LEN, "%s", mode);
|
||||
else
|
||||
@@ -149,79 +152,6 @@ int crypt_parse_pbkdf(const char *s, const char **pbkdf)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Replacement for memset(s, 0, n) on stack that can be optimized out
|
||||
* Also used in safe allocations for explicit memory wipe.
|
||||
*/
|
||||
void crypt_memzero(void *s, size_t n)
|
||||
{
|
||||
#ifdef HAVE_EXPLICIT_BZERO
|
||||
explicit_bzero(s, n);
|
||||
#else
|
||||
volatile uint8_t *p = (volatile uint8_t *)s;
|
||||
|
||||
while(n--)
|
||||
*p++ = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* safe allocations */
|
||||
void *crypt_safe_alloc(size_t size)
|
||||
{
|
||||
struct safe_allocation *alloc;
|
||||
|
||||
if (!size || size > (SIZE_MAX - offsetof(struct safe_allocation, data)))
|
||||
return NULL;
|
||||
|
||||
alloc = malloc(size + offsetof(struct safe_allocation, data));
|
||||
if (!alloc)
|
||||
return NULL;
|
||||
|
||||
alloc->size = size;
|
||||
crypt_memzero(&alloc->data, size);
|
||||
|
||||
/* coverity[leaked_storage] */
|
||||
return &alloc->data;
|
||||
}
|
||||
|
||||
void crypt_safe_free(void *data)
|
||||
{
|
||||
struct safe_allocation *alloc;
|
||||
|
||||
if (!data)
|
||||
return;
|
||||
|
||||
alloc = (struct safe_allocation *)
|
||||
((char *)data - offsetof(struct safe_allocation, data));
|
||||
|
||||
crypt_memzero(data, alloc->size);
|
||||
|
||||
alloc->size = 0x55aa55aa;
|
||||
free(alloc);
|
||||
}
|
||||
|
||||
void *crypt_safe_realloc(void *data, size_t size)
|
||||
{
|
||||
struct safe_allocation *alloc;
|
||||
void *new_data;
|
||||
|
||||
new_data = crypt_safe_alloc(size);
|
||||
|
||||
if (new_data && data) {
|
||||
|
||||
alloc = (struct safe_allocation *)
|
||||
((char *)data - offsetof(struct safe_allocation, data));
|
||||
|
||||
if (size > alloc->size)
|
||||
size = alloc->size;
|
||||
|
||||
memcpy(new_data, data, size);
|
||||
}
|
||||
|
||||
crypt_safe_free(data);
|
||||
return new_data;
|
||||
}
|
||||
|
||||
ssize_t crypt_hex_to_bytes(const char *hex, char **result, int safe_alloc)
|
||||
{
|
||||
char buf[3] = "xx\0", *endp, *bytes;
|
||||
@@ -247,3 +177,10 @@ ssize_t crypt_hex_to_bytes(const char *hex, char **result, int safe_alloc)
|
||||
*result = bytes;
|
||||
return i;
|
||||
}
|
||||
|
||||
bool crypt_is_cipher_null(const char *cipher_spec)
|
||||
{
|
||||
if (!cipher_spec)
|
||||
return false;
|
||||
return (strstr(cipher_spec, "cipher_null") || !strcmp(cipher_spec, "null"));
|
||||
}
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
* utils_crypt - cipher utilities for cryptsetup
|
||||
*
|
||||
* Copyright (C) 2004-2007 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2019 Milan Broz
|
||||
* Copyright (C) 2009-2021 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2021 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -23,20 +23,13 @@
|
||||
#ifndef _UTILS_CRYPT_H
|
||||
#define _UTILS_CRYPT_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define MAX_CIPHER_LEN 32
|
||||
#define MAX_CIPHER_LEN_STR "31"
|
||||
#define MAX_KEYFILES 32
|
||||
|
||||
struct crypt_device;
|
||||
|
||||
/* Not to be used directly */
|
||||
struct safe_allocation {
|
||||
size_t size;
|
||||
char data[0];
|
||||
};
|
||||
|
||||
int crypt_parse_name_and_mode(const char *s, char *cipher,
|
||||
int *key_nums, char *cipher_mode);
|
||||
int crypt_parse_hash_integrity_mode(const char *s, char *integrity);
|
||||
@@ -44,12 +37,8 @@ int crypt_parse_integrity_mode(const char *s, char *integrity,
|
||||
int *integrity_key_size);
|
||||
int crypt_parse_pbkdf(const char *s, const char **pbkdf);
|
||||
|
||||
void *crypt_safe_alloc(size_t size);
|
||||
void crypt_safe_free(void *data);
|
||||
void *crypt_safe_realloc(void *data, size_t size);
|
||||
|
||||
void crypt_memzero(void *s, size_t n);
|
||||
|
||||
ssize_t crypt_hex_to_bytes(const char *hex, char **result, int safe_alloc);
|
||||
|
||||
bool crypt_is_cipher_null(const char *cipher_spec);
|
||||
|
||||
#endif /* _UTILS_CRYPT_H */
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
*
|
||||
* Copyright (C) 2004 Jana Saout <jana@saout.de>
|
||||
* Copyright (C) 2004-2007 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2019 Milan Broz
|
||||
* Copyright (C) 2009-2021 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2021 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -24,7 +24,6 @@
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
@@ -145,7 +144,7 @@ static int device_read_test(int devfd)
|
||||
if (read_blockwise(devfd, blocksize, alignment, buffer, minsize) == (ssize_t)minsize)
|
||||
r = 0;
|
||||
|
||||
crypt_memzero(buffer, sizeof(buffer));
|
||||
crypt_safe_memzero(buffer, sizeof(buffer));
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -185,7 +184,7 @@ static int device_ready(struct crypt_device *cd, struct device *device)
|
||||
}
|
||||
|
||||
if (devfd < 0) {
|
||||
log_err(cd, _("Device %s doesn't exist or access denied."),
|
||||
log_err(cd, _("Device %s does not exist or access denied."),
|
||||
device_path(device));
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -301,6 +300,9 @@ static int device_open_internal(struct crypt_device *cd, struct device *device,
|
||||
|
||||
int device_open(struct crypt_device *cd, struct device *device, int flags)
|
||||
{
|
||||
if (!device)
|
||||
return -EINVAL;
|
||||
|
||||
assert(!device_locked(device->lh));
|
||||
return device_open_internal(cd, device, flags);
|
||||
}
|
||||
@@ -355,6 +357,9 @@ void device_release_excl(struct crypt_device *cd, struct device *device)
|
||||
|
||||
int device_open_locked(struct crypt_device *cd, struct device *device, int flags)
|
||||
{
|
||||
if (!device)
|
||||
return -EINVAL;
|
||||
|
||||
assert(!crypt_metadata_locking_enabled() || device_locked(device->lh));
|
||||
return device_open_internal(cd, device, flags);
|
||||
}
|
||||
@@ -521,10 +526,16 @@ void device_topology_alignment(struct crypt_device *cd,
|
||||
|
||||
temp_alignment = (unsigned long)min_io_size;
|
||||
|
||||
/* Ignore bogus opt-io that could break alignment */
|
||||
/*
|
||||
* Ignore bogus opt-io that could break alignment.
|
||||
* Also real opt_io_size should be aligned to minimal page size (4k).
|
||||
* Some bogus USB enclosures reports wrong data here.
|
||||
*/
|
||||
if ((temp_alignment < (unsigned long)opt_io_size) &&
|
||||
!((unsigned long)opt_io_size % temp_alignment))
|
||||
!((unsigned long)opt_io_size % temp_alignment) && !MISALIGNED_4K(opt_io_size))
|
||||
temp_alignment = (unsigned long)opt_io_size;
|
||||
else if (opt_io_size && (opt_io_size != min_io_size))
|
||||
log_err(cd, _("Ignoring bogus optimal-io size for data device (%u bytes)."), opt_io_size);
|
||||
|
||||
/* If calculated alignment is multiple of default, keep default */
|
||||
if (temp_alignment && (default_alignment % temp_alignment))
|
||||
@@ -584,8 +595,11 @@ int device_size(struct device *device, uint64_t *size)
|
||||
struct stat st;
|
||||
int devfd, r = -EINVAL;
|
||||
|
||||
if (!device)
|
||||
return -EINVAL;
|
||||
|
||||
devfd = open(device->path, O_RDONLY);
|
||||
if(devfd == -1)
|
||||
if (devfd == -1)
|
||||
return -EINVAL;
|
||||
|
||||
if (fstat(devfd, &st) < 0)
|
||||
@@ -607,6 +621,9 @@ int device_fallocate(struct device *device, uint64_t size)
|
||||
struct stat st;
|
||||
int devfd, r = -EINVAL;
|
||||
|
||||
if (!device)
|
||||
return -EINVAL;
|
||||
|
||||
devfd = open(device_path(device), O_RDWR);
|
||||
if (devfd == -1)
|
||||
return -EINVAL;
|
||||
@@ -847,22 +864,30 @@ size_t size_round_up(size_t size, size_t block)
|
||||
|
||||
void device_disable_direct_io(struct device *device)
|
||||
{
|
||||
device->o_direct = 0;
|
||||
if (device)
|
||||
device->o_direct = 0;
|
||||
}
|
||||
|
||||
int device_direct_io(const struct device *device)
|
||||
{
|
||||
return device->o_direct;
|
||||
return device ? device->o_direct : 0;
|
||||
}
|
||||
|
||||
static dev_t device_devno(const struct device *device)
|
||||
static int device_compare_path(const char *path1, const char *path2)
|
||||
{
|
||||
struct stat st;
|
||||
struct stat st_path1, st_path2;
|
||||
|
||||
if (stat(device->path, &st) || !S_ISBLK(st.st_mode))
|
||||
return 0;
|
||||
if (stat(path1, &st_path1 ) < 0 || stat(path2, &st_path2 ) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
return st.st_rdev;
|
||||
if (S_ISBLK(st_path1.st_mode) && S_ISBLK(st_path2.st_mode))
|
||||
return (st_path1.st_rdev == st_path2.st_rdev) ? 1 : 0;
|
||||
|
||||
if (S_ISREG(st_path1.st_mode) && S_ISREG(st_path2.st_mode))
|
||||
return (st_path1.st_ino == st_path2.st_ino &&
|
||||
st_path1.st_dev == st_path2.st_dev) ? 1 : 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int device_is_identical(struct device *device1, struct device *device2)
|
||||
@@ -873,21 +898,19 @@ int device_is_identical(struct device *device1, struct device *device2)
|
||||
if (device1 == device2)
|
||||
return 1;
|
||||
|
||||
if (device1->init_done && device2->init_done)
|
||||
return (device_devno(device1) == device_devno(device2));
|
||||
else if (device1->init_done || device2->init_done)
|
||||
return 0;
|
||||
|
||||
if (!strcmp(device_path(device1), device_path(device2)))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
return device_compare_path(device_path(device1), device_path(device2));
|
||||
}
|
||||
|
||||
int device_is_rotational(struct device *device)
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
if (!device)
|
||||
return -EINVAL;
|
||||
|
||||
if (stat(device_path(device), &st) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
@@ -901,6 +924,9 @@ size_t device_alignment(struct device *device)
|
||||
{
|
||||
int devfd;
|
||||
|
||||
if (!device)
|
||||
return -EINVAL;
|
||||
|
||||
if (!device->alignment) {
|
||||
devfd = open(device_path(device), O_RDONLY);
|
||||
if (devfd != -1) {
|
||||
@@ -914,17 +940,18 @@ size_t device_alignment(struct device *device)
|
||||
|
||||
void device_set_lock_handle(struct device *device, struct crypt_lock_handle *h)
|
||||
{
|
||||
device->lh = h;
|
||||
if (device)
|
||||
device->lh = h;
|
||||
}
|
||||
|
||||
struct crypt_lock_handle *device_get_lock_handle(struct device *device)
|
||||
{
|
||||
return device->lh;
|
||||
return device ? device->lh : NULL;
|
||||
}
|
||||
|
||||
int device_read_lock(struct crypt_device *cd, struct device *device)
|
||||
{
|
||||
if (!crypt_metadata_locking_enabled())
|
||||
if (!device || !crypt_metadata_locking_enabled())
|
||||
return 0;
|
||||
|
||||
if (device_read_lock_internal(cd, device))
|
||||
@@ -935,7 +962,7 @@ int device_read_lock(struct crypt_device *cd, struct device *device)
|
||||
|
||||
int device_write_lock(struct crypt_device *cd, struct device *device)
|
||||
{
|
||||
if (!crypt_metadata_locking_enabled())
|
||||
if (!device || !crypt_metadata_locking_enabled())
|
||||
return 0;
|
||||
|
||||
assert(!device_locked(device->lh) || !device_locked_readonly(device->lh));
|
||||
@@ -945,7 +972,7 @@ int device_write_lock(struct crypt_device *cd, struct device *device)
|
||||
|
||||
void device_read_unlock(struct crypt_device *cd, struct device *device)
|
||||
{
|
||||
if (!crypt_metadata_locking_enabled())
|
||||
if (!device || !crypt_metadata_locking_enabled())
|
||||
return;
|
||||
|
||||
assert(device_locked(device->lh));
|
||||
@@ -955,7 +982,7 @@ void device_read_unlock(struct crypt_device *cd, struct device *device)
|
||||
|
||||
void device_write_unlock(struct crypt_device *cd, struct device *device)
|
||||
{
|
||||
if (!crypt_metadata_locking_enabled())
|
||||
if (!device || !crypt_metadata_locking_enabled())
|
||||
return;
|
||||
|
||||
assert(device_locked(device->lh) && !device_locked_readonly(device->lh));
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* Metadata on-disk locking for processes serialization
|
||||
*
|
||||
* Copyright (C) 2016-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2016-2019 Ondrej Kozina
|
||||
* Copyright (C) 2016-2021 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2016-2021 Ondrej Kozina
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -20,7 +20,6 @@
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <linux/limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@@ -107,7 +106,7 @@ static int open_lock_dir(struct crypt_device *cd, const char *dir, const char *b
|
||||
lockdfd = openat(dirfd, base, O_RDONLY | O_NOFOLLOW | O_DIRECTORY | O_CLOEXEC);
|
||||
if (lockdfd < 0) {
|
||||
if (errno == ENOENT) {
|
||||
log_std(cd, _("WARNING: Locking directory %s/%s is missing!\n"), dir, base);
|
||||
log_dbg(cd, _("Locking directory %s/%s will be created with default compiled-in permissions."), dir, base);
|
||||
|
||||
/* success or failure w/ errno == EEXIST either way just try to open the 'base' directory again */
|
||||
if (mkdirat(dirfd, base, DEFAULT_LUKS2_LOCK_DIR_PERMS) && errno != EEXIST)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* Metadata on-disk locking for processes serialization
|
||||
*
|
||||
* Copyright (C) 2016-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2016-2019 Ondrej Kozina
|
||||
* Copyright (C) 2016-2021 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2016-2021 Ondrej Kozina
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -22,6 +22,8 @@
|
||||
#ifndef _CRYPTSETUP_UTILS_LOCKING_H
|
||||
#define _CRYPTSETUP_UTILS_LOCKING_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
struct crypt_device;
|
||||
struct crypt_lock_handle;
|
||||
struct device;
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
*
|
||||
* Copyright (C) 2004 Jana Saout <jana@saout.de>
|
||||
* Copyright (C) 2004-2007 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2019 Milan Broz
|
||||
* Copyright (C) 2009-2021 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2021 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -26,7 +26,6 @@
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <dirent.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
*
|
||||
* Copyright (C) 2004 Jana Saout <jana@saout.de>
|
||||
* Copyright (C) 2004-2007 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2019 Milan Broz
|
||||
* Copyright (C) 2009-2021 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2021 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -25,7 +25,8 @@
|
||||
#define _UTILS_DM_H
|
||||
|
||||
/* device-mapper library helpers */
|
||||
#include <inttypes.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
struct crypt_device;
|
||||
struct volume_key;
|
||||
@@ -64,8 +65,16 @@ static inline uint32_t act2dmflags(uint32_t act_flags)
|
||||
#define DM_INTEGRITY_RECALC_SUPPORTED (1 << 16) /* dm-integrity automatic recalculation supported */
|
||||
#define DM_INTEGRITY_BITMAP_SUPPORTED (1 << 17) /* dm-integrity bitmap mode supported */
|
||||
#define DM_GET_TARGET_VERSION_SUPPORTED (1 << 18) /* dm DM_GET_TARGET version ioctl supported */
|
||||
#define DM_INTEGRITY_FIX_PADDING_SUPPORTED (1 << 19) /* supports the parameter fix_padding that fixes a bug that caused excessive padding */
|
||||
#define DM_BITLK_EBOIV_SUPPORTED (1 << 20) /* EBOIV for BITLK supported */
|
||||
#define DM_BITLK_ELEPHANT_SUPPORTED (1 << 21) /* Elephant diffuser for BITLK supported */
|
||||
#define DM_VERITY_SIGNATURE_SUPPORTED (1 << 22) /* Verity option root_hash_sig_key_desc supported */
|
||||
#define DM_INTEGRITY_DISCARDS_SUPPORTED (1 << 23) /* dm-integrity discards/TRIM option is supported */
|
||||
#define DM_VERITY_PANIC_CORRUPTION_SUPPORTED (1 << 24) /* dm-verity panic on corruption */
|
||||
#define DM_CRYPT_NO_WORKQUEUE_SUPPORTED (1 << 25) /* dm-crypt suppot for bypassing workqueues */
|
||||
#define DM_INTEGRITY_FIX_HMAC_SUPPORTED (1 << 26) /* hmac covers also superblock */
|
||||
|
||||
typedef enum { DM_CRYPT = 0, DM_VERITY, DM_INTEGRITY, DM_LINEAR, DM_ERROR, DM_UNKNOWN } dm_target_type;
|
||||
typedef enum { DM_CRYPT = 0, DM_VERITY, DM_INTEGRITY, DM_LINEAR, DM_ERROR, DM_ZERO, DM_UNKNOWN } dm_target_type;
|
||||
enum tdirection { TARGET_SET = 1, TARGET_QUERY };
|
||||
|
||||
int dm_flags(struct crypt_device *cd, dm_target_type target, uint32_t *flags);
|
||||
@@ -110,11 +119,11 @@ struct dm_target {
|
||||
|
||||
const char *root_hash;
|
||||
uint32_t root_hash_size;
|
||||
const char *root_hash_sig_key_desc;
|
||||
|
||||
uint64_t hash_offset; /* hash offset in blocks (not header) */
|
||||
uint64_t hash_blocks; /* size of hash device (in hash blocks) */
|
||||
uint64_t fec_offset; /* FEC offset in blocks (not header) */
|
||||
uint64_t fec_blocks; /* size of FEC device (in hash blocks) */
|
||||
uint64_t fec_blocks; /* FEC blocks covering data + hash + padding (foreign metadata)*/
|
||||
struct crypt_params_verity *vp;
|
||||
} verity;
|
||||
struct {
|
||||
@@ -138,10 +147,16 @@ struct dm_target {
|
||||
struct volume_key *journal_crypt_key;
|
||||
|
||||
struct device *meta_device;
|
||||
|
||||
bool fix_padding;
|
||||
bool fix_hmac;
|
||||
bool legacy_recalc;
|
||||
} integrity;
|
||||
struct {
|
||||
uint64_t offset;
|
||||
} linear;
|
||||
struct {
|
||||
} zero;
|
||||
} u;
|
||||
|
||||
char *params;
|
||||
@@ -175,9 +190,10 @@ int dm_crypt_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t seg
|
||||
uint32_t tag_size, uint32_t sector_size);
|
||||
int dm_verity_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t seg_size,
|
||||
struct device *data_device, struct device *hash_device, struct device *fec_device,
|
||||
const char *root_hash, uint32_t root_hash_size, uint64_t hash_offset_block,
|
||||
uint64_t hash_blocks, struct crypt_params_verity *vp);
|
||||
int dm_integrity_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t seg_size,
|
||||
const char *root_hash, uint32_t root_hash_size, const char* root_hash_sig_key_desc,
|
||||
uint64_t hash_offset_block, uint64_t fec_blocks, struct crypt_params_verity *vp);
|
||||
int dm_integrity_target_set(struct crypt_device *cd,
|
||||
struct dm_target *tgt, uint64_t seg_offset, uint64_t seg_size,
|
||||
struct device *meta_device,
|
||||
struct device *data_device, uint64_t tag_size, uint64_t offset, uint32_t sector_size,
|
||||
struct volume_key *vk,
|
||||
@@ -185,6 +201,7 @@ int dm_integrity_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t
|
||||
const struct crypt_params_integrity *ip);
|
||||
int dm_linear_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t seg_size,
|
||||
struct device *data_device, uint64_t data_offset);
|
||||
int dm_zero_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t seg_size);
|
||||
|
||||
int dm_remove_device(struct crypt_device *cd, const char *name, uint32_t flags);
|
||||
int dm_status_device(struct crypt_device *cd, const char *name);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* FIPS mode utilities
|
||||
*
|
||||
* Copyright (C) 2011-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2011-2021 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* FIPS mode utilities
|
||||
*
|
||||
* Copyright (C) 2011-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2011-2021 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
*
|
||||
* Copyright (C) 2004 Jana Saout <jana@saout.de>
|
||||
* Copyright (C) 2004-2007 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2019 Milan Broz
|
||||
* Copyright (C) 2009-2021 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2021 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
*
|
||||
* Copyright (C) 2004 Jana Saout <jana@saout.de>
|
||||
* Copyright (C) 2004-2007 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2019 Milan Broz
|
||||
* Copyright (C) 2009-2021 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2021 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* kernel keyring utilities
|
||||
*
|
||||
* Copyright (C) 2016-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2016-2019 Ondrej Kozina
|
||||
* Copyright (C) 2016-2021 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2016-2021 Ondrej Kozina
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -25,15 +25,14 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/syscall.h>
|
||||
|
||||
#include "libcryptsetup.h"
|
||||
#include "utils_keyring.h"
|
||||
|
||||
#ifndef HAVE_KEY_SERIAL_T
|
||||
#define HAVE_KEY_SERIAL_T
|
||||
#include <stdint.h>
|
||||
typedef int32_t key_serial_t;
|
||||
#endif
|
||||
|
||||
#include "utils_crypt.h"
|
||||
#include "utils_keyring.h"
|
||||
|
||||
#ifndef ARRAY_SIZE
|
||||
# define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
|
||||
#endif
|
||||
@@ -178,7 +177,7 @@ int keyring_get_passphrase(const char *key_desc,
|
||||
if (ret < 0) {
|
||||
err = errno;
|
||||
if (buf)
|
||||
crypt_memzero(buf, len);
|
||||
crypt_safe_memzero(buf, len);
|
||||
free(buf);
|
||||
return -err;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* kernel keyring syscall wrappers
|
||||
*
|
||||
* Copyright (C) 2016-2019 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2016-2019 Ondrej Kozina
|
||||
* Copyright (C) 2016-2021 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2016-2021 Ondrej Kozina
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user