mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-05 16:00:05 +01:00
Compare commits
626 Commits
v2.7.0-rc0
...
ffe169aa48
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ffe169aa48 | ||
|
|
f1ba606c28 | ||
|
|
5d69c34f59 | ||
|
|
e1cbd4ecba | ||
|
|
9ea9af1bcd | ||
|
|
4fe1601d9c | ||
|
|
72173b2777 | ||
|
|
f304132b2b | ||
|
|
0779c8ceed | ||
|
|
153aed3d16 | ||
|
|
8a3e16fa25 | ||
|
|
8da66c3066 | ||
|
|
11a4fc6790 | ||
|
|
e4c498d15b | ||
|
|
e609c47916 | ||
|
|
ccc0c69cd7 | ||
|
|
7fba92260a | ||
|
|
76ea8f13cf | ||
|
|
bbc053682a | ||
|
|
c9fd8b5ed4 | ||
|
|
fbd295259c | ||
|
|
5490d28aa4 | ||
|
|
296eb39c60 | ||
|
|
917b6836a9 | ||
|
|
b36d4be8fa | ||
|
|
0a8e7da7ae | ||
|
|
83a7310ca2 | ||
|
|
441802773f | ||
|
|
cc66b1fa52 | ||
|
|
a0d5d2bf5e | ||
|
|
61dbb69319 | ||
|
|
32b33541a8 | ||
|
|
346db2e42a | ||
|
|
0d07e80077 | ||
|
|
dc2251b88d | ||
|
|
a8e8e39007 | ||
|
|
bcef385346 | ||
|
|
9810c6fb2f | ||
|
|
4d98add260 | ||
|
|
0eaaa4553e | ||
|
|
3a8feb8be7 | ||
|
|
2b9523a1ef | ||
|
|
68d4749d8a | ||
|
|
9cfdd6ba06 | ||
|
|
4749473c39 | ||
|
|
4a1384452c | ||
|
|
b0821b11a5 | ||
|
|
098d2122e5 | ||
|
|
df58aa5aee | ||
|
|
9e9f6bcb5b | ||
|
|
c8166fc696 | ||
|
|
c48cac6c65 | ||
|
|
c9d32b7462 | ||
|
|
c91d641e0c | ||
|
|
5ac42f98bd | ||
|
|
d825083baa | ||
|
|
79b09a897f | ||
|
|
a42083e6c8 | ||
|
|
b8d3ff3b1a | ||
|
|
b7ec4a9d9b | ||
|
|
10e5ab1a87 | ||
|
|
57a8837879 | ||
|
|
b0d38f932f | ||
|
|
b7e3ea592b | ||
|
|
c618a50de8 | ||
|
|
7b43c6a784 | ||
|
|
149a414c93 | ||
|
|
e33a315776 | ||
|
|
8546260a49 | ||
|
|
fa5ab78837 | ||
|
|
80a1ebe93e | ||
|
|
70a69b5059 | ||
|
|
32e9bed060 | ||
|
|
12eaacaaaf | ||
|
|
d0312d6c34 | ||
|
|
4a67af439e | ||
|
|
d77ece493d | ||
|
|
04d307d9c0 | ||
|
|
6c7c8d36bb | ||
|
|
b6ddaa40bf | ||
|
|
1c75cd0dc4 | ||
|
|
267de08586 | ||
|
|
e0a5fb2c25 | ||
|
|
b995ab243c | ||
|
|
a498757fd4 | ||
|
|
349912fec2 | ||
|
|
b0e3b94839 | ||
|
|
c66c520e26 | ||
|
|
2c95933bb5 | ||
|
|
bc1b149ee4 | ||
|
|
55272bee98 | ||
|
|
9590d6fe62 | ||
|
|
5af06cb6cc | ||
|
|
a9e245f68c | ||
|
|
74a4de9fdd | ||
|
|
2d4c40e627 | ||
|
|
2cf4c9a360 | ||
|
|
360f85dde7 | ||
|
|
1438140ce3 | ||
|
|
a52e1aadca | ||
|
|
19a4f53c07 | ||
|
|
8a73750ba9 | ||
|
|
db720abcc3 | ||
|
|
ebbecb6df0 | ||
|
|
830bd02160 | ||
|
|
ea96360efc | ||
|
|
eb9f0a63b8 | ||
|
|
13306948c8 | ||
|
|
cdc451a61a | ||
|
|
04ca5087f8 | ||
|
|
2262641c74 | ||
|
|
232ba8dd3a | ||
|
|
3490944c27 | ||
|
|
e8c32e5c41 | ||
|
|
ccc9a977f7 | ||
|
|
a0929f67f1 | ||
|
|
e57f1b3dd8 | ||
|
|
e9a20ad3dc | ||
|
|
f3d348776d | ||
|
|
e9c626cccd | ||
|
|
ef592405dd | ||
|
|
5ce481a8c2 | ||
|
|
9b5ed35078 | ||
|
|
bf7d2c5a3b | ||
|
|
a8105ef9bb | ||
|
|
96787457e1 | ||
|
|
849bd0d2f3 | ||
|
|
f866a663b0 | ||
|
|
bac868b392 | ||
|
|
7ed0934892 | ||
|
|
6db3fa33e1 | ||
|
|
255336b309 | ||
|
|
084b1d2984 | ||
|
|
d0b582bbd6 | ||
|
|
b84ffc4ff4 | ||
|
|
c7f3f32ec9 | ||
|
|
f221de22b6 | ||
|
|
ff4aa8e5e7 | ||
|
|
efc6f847ee | ||
|
|
30ede1be36 | ||
|
|
98323a93a8 | ||
|
|
700047c84f | ||
|
|
10ab6be262 | ||
|
|
ad30673dc5 | ||
|
|
773ac1ce55 | ||
|
|
ed50d30e7e | ||
|
|
5973694311 | ||
|
|
b81c84bd8f | ||
|
|
8d7ee84006 | ||
|
|
21e0680abf | ||
|
|
bd03054c38 | ||
|
|
e136a0a40a | ||
|
|
5b3ff3c0a7 | ||
|
|
c3414b8221 | ||
|
|
9f8667922c | ||
|
|
949c4ad0f1 | ||
|
|
55c44cd3fd | ||
|
|
ca7c4c8b15 | ||
|
|
a6c9c28208 | ||
|
|
b6f43890f2 | ||
|
|
c735c71ca1 | ||
|
|
f3557f0765 | ||
|
|
5a2ca129b9 | ||
|
|
5755f210ac | ||
|
|
ccf7d6b197 | ||
|
|
19d67d3c62 | ||
|
|
cf630f578d | ||
|
|
12eb040943 | ||
|
|
880bbfab4d | ||
|
|
e6f6ee9291 | ||
|
|
6b832b8d03 | ||
|
|
f29337aa9f | ||
|
|
f5bbc499d4 | ||
|
|
4fd3db5e93 | ||
|
|
cbf6fa9d07 | ||
|
|
9e4a31887e | ||
|
|
680567615a | ||
|
|
24b126252b | ||
|
|
324926e2d8 | ||
|
|
3ec14c8668 | ||
|
|
d967c9aaf0 | ||
|
|
352cda0302 | ||
|
|
006ebd832f | ||
|
|
49ccafe38a | ||
|
|
29fcd88d86 | ||
|
|
c4ce270568 | ||
|
|
8440e59b7b | ||
|
|
465043300d | ||
|
|
50b762ab94 | ||
|
|
11dd8d318c | ||
|
|
e5c2892cd5 | ||
|
|
bd2f7eb671 | ||
|
|
a39a0d00e5 | ||
|
|
9484eee48a | ||
|
|
5689fb46e7 | ||
|
|
4d5aa29955 | ||
|
|
ad21502d06 | ||
|
|
0dc630b911 | ||
|
|
cbcb8c6ee3 | ||
|
|
5a84dc87e3 | ||
|
|
1a7e89c55d | ||
|
|
804ee74a46 | ||
|
|
b497306934 | ||
|
|
6c74b6f9c8 | ||
|
|
548de244c5 | ||
|
|
0363ea7c57 | ||
|
|
ae2a7cfc33 | ||
|
|
4e94c8d809 | ||
|
|
3dcb532bd3 | ||
|
|
02a48caf7e | ||
|
|
bc6c3092fa | ||
|
|
0cf87a4151 | ||
|
|
cf29d51589 | ||
|
|
8fcd8a78d8 | ||
|
|
5f48657f4d | ||
|
|
4493d9ad3e | ||
|
|
9f0dd9cc4c | ||
|
|
261bef3409 | ||
|
|
ff7a21eb94 | ||
|
|
48683f7316 | ||
|
|
e48d5b6d19 | ||
|
|
723ad6afdf | ||
|
|
79d8a8b840 | ||
|
|
5f8cab5d4a | ||
|
|
dd68e53082 | ||
|
|
9153c9c3c0 | ||
|
|
c1b5e412c9 | ||
|
|
fa84cb8a55 | ||
|
|
221d6ac345 | ||
|
|
d2fc31da28 | ||
|
|
8b14558b94 | ||
|
|
e936d4395b | ||
|
|
b166747fee | ||
|
|
3e114bcb1e | ||
|
|
1df9a4c566 | ||
|
|
7f0724f46c | ||
|
|
c8420de4d6 | ||
|
|
a0b4ae7e27 | ||
|
|
4b39379c5b | ||
|
|
70f0938fff | ||
|
|
fbb8d2e910 | ||
|
|
9e6fcefefc | ||
|
|
bf5d56d804 | ||
|
|
c1b7ad8979 | ||
|
|
fcf266667b | ||
|
|
cb0f568932 | ||
|
|
000f03ad31 | ||
|
|
07e8628940 | ||
|
|
fdb179ea8b | ||
|
|
b91aee46c1 | ||
|
|
eccccfd9b5 | ||
|
|
2dc886053f | ||
|
|
0a6ee8633a | ||
|
|
15c4a410fd | ||
|
|
5615488196 | ||
|
|
c9edd942e8 | ||
|
|
d792de66d5 | ||
|
|
848f16bb5e | ||
|
|
8573eb515d | ||
|
|
b2da80909a | ||
|
|
db57571906 | ||
|
|
93bc8997ea | ||
|
|
52c63b5de1 | ||
|
|
dded9b3305 | ||
|
|
41b8b02ccf | ||
|
|
7ee0b02967 | ||
|
|
a3455befe7 | ||
|
|
f07854ab4f | ||
|
|
c497945ab3 | ||
|
|
036ed52999 | ||
|
|
1bec71dbe1 | ||
|
|
9e0bcedbaa | ||
|
|
6123ea2e0b | ||
|
|
f421ec0800 | ||
|
|
843fac813f | ||
|
|
6ee76934fa | ||
|
|
f86ab28ad6 | ||
|
|
54d937dfc7 | ||
|
|
fd9be9e777 | ||
|
|
63f7dc739b | ||
|
|
a2b2c6a8ae | ||
|
|
3899484be8 | ||
|
|
a965a88992 | ||
|
|
88b3da6042 | ||
|
|
1326dfbac1 | ||
|
|
4f90213a5b | ||
|
|
5ee549de1e | ||
|
|
e9073e6b19 | ||
|
|
dc75deff51 | ||
|
|
ab9d4fec3b | ||
|
|
da84c79a5b | ||
|
|
a321068e8d | ||
|
|
e257def910 | ||
|
|
c9008528f9 | ||
|
|
3d535dcf31 | ||
|
|
a45fb0a90d | ||
|
|
06c0f03c9f | ||
|
|
c6a7849090 | ||
|
|
29741d91e6 | ||
|
|
1e441bf75c | ||
|
|
d9404821a6 | ||
|
|
e5405f2fd8 | ||
|
|
37d52876b9 | ||
|
|
ff81791308 | ||
|
|
c21c746eff | ||
|
|
bb304f45bd | ||
|
|
f64f6fb9e8 | ||
|
|
5c795885c5 | ||
|
|
6a8f88ea99 | ||
|
|
7ffa8ee28a | ||
|
|
2691514547 | ||
|
|
36574dd114 | ||
|
|
8364178b38 | ||
|
|
2a880f838a | ||
|
|
e6208a12b5 | ||
|
|
b54e5ce9f0 | ||
|
|
bfae421c52 | ||
|
|
33ebb36f71 | ||
|
|
64fb1c1b26 | ||
|
|
b18cefcc71 | ||
|
|
7cabaa5d70 | ||
|
|
b201a62987 | ||
|
|
f8788f347e | ||
|
|
ea39aecba3 | ||
|
|
5eda5f6a38 | ||
|
|
b5672053f5 | ||
|
|
491f31c4d4 | ||
|
|
7b5ac650e5 | ||
|
|
ff3e2c6a43 | ||
|
|
1bea029cef | ||
|
|
ecb1326e0e | ||
|
|
690c22ac7b | ||
|
|
9f1aee46d5 | ||
|
|
82bee1c52d | ||
|
|
0805cc025d | ||
|
|
9d03e5987c | ||
|
|
768bca1df5 | ||
|
|
4b7920975c | ||
|
|
42e85571df | ||
|
|
ae4b4ff4d7 | ||
|
|
9575dadc8b | ||
|
|
6be70a0157 | ||
|
|
3acac6f8fc | ||
|
|
609277d957 | ||
|
|
fb021bac3d | ||
|
|
c3972372b1 | ||
|
|
46289f92ff | ||
|
|
3c5aa4ef59 | ||
|
|
5e950924c3 | ||
|
|
76d66d6a01 | ||
|
|
ccbc53c169 | ||
|
|
61aaeaff5a | ||
|
|
dd3441621a | ||
|
|
d7512d738f | ||
|
|
6506d324ee | ||
|
|
a93921c226 | ||
|
|
f5b7a576b3 | ||
|
|
c0449fc24e | ||
|
|
17f0261024 | ||
|
|
6daefa8222 | ||
|
|
33ed0d587e | ||
|
|
f85c31677c | ||
|
|
5b83ae8ec2 | ||
|
|
7db83f8fb3 | ||
|
|
652835a1f8 | ||
|
|
00b89c4862 | ||
|
|
305aa376b6 | ||
|
|
651a089f38 | ||
|
|
45af8de034 | ||
|
|
0eccd6e194 | ||
|
|
4de453d6a5 | ||
|
|
66c1523163 | ||
|
|
5f066777a1 | ||
|
|
fb04611ff7 | ||
|
|
b7cf60f229 | ||
|
|
81d8c12cbe | ||
|
|
e19030915b | ||
|
|
e4bf1f91b9 | ||
|
|
7c83d4e639 | ||
|
|
939b7c0a9e | ||
|
|
443a555559 | ||
|
|
79ef5bee86 | ||
|
|
cd818156f6 | ||
|
|
faeb0c3483 | ||
|
|
d35fb1e671 | ||
|
|
8ad28547ee | ||
|
|
3c00305156 | ||
|
|
31bf986084 | ||
|
|
6ef0650332 | ||
|
|
9311c923ca | ||
|
|
209e6167b5 | ||
|
|
b5f7176af1 | ||
|
|
c0bf271bef | ||
|
|
41c72eaa65 | ||
|
|
e48c74b77f | ||
|
|
46b8275ad9 | ||
|
|
beef8e325a | ||
|
|
63bb997b41 | ||
|
|
9991cbc306 | ||
|
|
4cdd022ba4 | ||
|
|
e4d25d18eb | ||
|
|
3d89faca18 | ||
|
|
a42bd088b5 | ||
|
|
aeada055d1 | ||
|
|
53198bdea9 | ||
|
|
da09835b6c | ||
|
|
42f4a68705 | ||
|
|
d5fb76a3b4 | ||
|
|
7c992fa09e | ||
|
|
35bf791e85 | ||
|
|
0d4027291a | ||
|
|
e0852d21dd | ||
|
|
3a7794795f | ||
|
|
8be7b01ba8 | ||
|
|
2bcdb5127a | ||
|
|
002f73b360 | ||
|
|
ec9b97a731 | ||
|
|
5873a65183 | ||
|
|
d88a97b1a0 | ||
|
|
3dc5d50918 | ||
|
|
021e5c31fd | ||
|
|
624b7087b0 | ||
|
|
cb7b7fd863 | ||
|
|
4daf8ef0dc | ||
|
|
2d041439bc | ||
|
|
7fa19da140 | ||
|
|
a9617c7c4a | ||
|
|
ce38d82025 | ||
|
|
5e04a82e53 | ||
|
|
3839e2bf98 | ||
|
|
8accd612a3 | ||
|
|
fddec0f2d7 | ||
|
|
7a816abf82 | ||
|
|
94f37efb57 | ||
|
|
5fb6d711c1 | ||
|
|
b0be186f9e | ||
|
|
b1cc660df3 | ||
|
|
35a9f08062 | ||
|
|
9c47812904 | ||
|
|
8b21b4b2ee | ||
|
|
bf088de00f | ||
|
|
1423c6eac2 | ||
|
|
e5b430cdc1 | ||
|
|
a5e409c186 | ||
|
|
0cc686af59 | ||
|
|
14fd0b5fc1 | ||
|
|
9651d1f376 | ||
|
|
98b4243432 | ||
|
|
e32ea56b59 | ||
|
|
afee503e34 | ||
|
|
7019f42ff1 | ||
|
|
647b24f706 | ||
|
|
0cff233af1 | ||
|
|
8cb3b32070 | ||
|
|
8109b10ea4 | ||
|
|
d9660cf221 | ||
|
|
29f1f71c67 | ||
|
|
1d9a362113 | ||
|
|
e92763a61c | ||
|
|
9bdb7fee34 | ||
|
|
51c672ea62 | ||
|
|
b19170e8fe | ||
|
|
97c5f47c94 | ||
|
|
494c510c34 | ||
|
|
2a13ef5dd8 | ||
|
|
4708884d8c | ||
|
|
8f4a149ed3 | ||
|
|
d590c74a0e | ||
|
|
1a6a611dff | ||
|
|
661f57def4 | ||
|
|
8448448aa2 | ||
|
|
329fa3c54e | ||
|
|
1eb3df45dd | ||
|
|
af99b9b9d9 | ||
|
|
6859993ea7 | ||
|
|
bd8cfe1efb | ||
|
|
c2c1d59ff2 | ||
|
|
dca99f7dc1 | ||
|
|
9b822800b3 | ||
|
|
0d6d4e4255 | ||
|
|
a8e5bb0ebe | ||
|
|
aa69fc342a | ||
|
|
d0678c208d | ||
|
|
c21ccd89e3 | ||
|
|
0f20e14c67 | ||
|
|
1e58ad570e | ||
|
|
73975857a3 | ||
|
|
3c79fd6c4b | ||
|
|
82118bdd5f | ||
|
|
3e01e151f8 | ||
|
|
e085ae461f | ||
|
|
4a40d79322 | ||
|
|
ea32731e5b | ||
|
|
42a073c0cb | ||
|
|
738b9ee645 | ||
|
|
94ef8a7610 | ||
|
|
410a586284 | ||
|
|
40e5c7d095 | ||
|
|
4322ddbcb3 | ||
|
|
7b3a341809 | ||
|
|
40e56e969c | ||
|
|
c5d4b845df | ||
|
|
aae5cba2b9 | ||
|
|
bede116926 | ||
|
|
33e26be58b | ||
|
|
842d9e6e6e | ||
|
|
bc62204a41 | ||
|
|
4bd64eed82 | ||
|
|
4b0ae54379 | ||
|
|
69920581a3 | ||
|
|
4bf6db5ce8 | ||
|
|
a89485924c | ||
|
|
0cbeb35a93 | ||
|
|
e17ec37341 | ||
|
|
1ba758cde1 | ||
|
|
87bf39f71e | ||
|
|
1ae70b8c16 | ||
|
|
3d82771418 | ||
|
|
3e29dbe6f2 | ||
|
|
a462dbeb4e | ||
|
|
8655093cb7 | ||
|
|
25b543d371 | ||
|
|
6b3f9cd4bc | ||
|
|
608e42c574 | ||
|
|
143a76a5fa | ||
|
|
9906bc40e1 | ||
|
|
dc669a14d3 | ||
|
|
8819194281 | ||
|
|
5d6fbf7b53 | ||
|
|
4347a01cce | ||
|
|
6525b40a7b | ||
|
|
31573693a0 | ||
|
|
accc9c0ee9 | ||
|
|
5ec40f98ac | ||
|
|
5eb9c8b27a | ||
|
|
eccd46206d | ||
|
|
8d6fc937da | ||
|
|
41755b71b6 | ||
|
|
201a4b7d8b | ||
|
|
33b9a51fa8 | ||
|
|
9d38ea70e2 | ||
|
|
2cd0be9501 | ||
|
|
5a0208cd06 | ||
|
|
db635c428b | ||
|
|
678b28989b | ||
|
|
82f37d7a10 | ||
|
|
cbf818a660 | ||
|
|
3ff8d55a8b | ||
|
|
349572e69e | ||
|
|
0725efefa7 | ||
|
|
af35c93332 | ||
|
|
193f8ff595 | ||
|
|
f91524dc63 | ||
|
|
f8e79cdbe6 | ||
|
|
35cd898c63 | ||
|
|
91c1d2202a | ||
|
|
a6d9dc0a16 | ||
|
|
f681194b57 | ||
|
|
fdac0d7ee2 | ||
|
|
b417154e71 | ||
|
|
4dde8f078f | ||
|
|
f11af15cd0 | ||
|
|
bd0ef58b3a | ||
|
|
cbc7253400 | ||
|
|
35ec935cc2 | ||
|
|
7eca077490 | ||
|
|
8dd3266599 | ||
|
|
135ed491d1 | ||
|
|
de1cd97fde | ||
|
|
f040f74f46 | ||
|
|
136ba21c65 | ||
|
|
7fb98caa79 | ||
|
|
4321992561 | ||
|
|
f354a0b038 | ||
|
|
5814b39cdd | ||
|
|
e0eb4dad95 | ||
|
|
0ba3e3077c | ||
|
|
dfe241dc24 | ||
|
|
001f228059 | ||
|
|
89ee1ed656 | ||
|
|
cac3184da3 | ||
|
|
b048a417b7 | ||
|
|
cfdb1b93af | ||
|
|
d15447814a | ||
|
|
912d410458 | ||
|
|
d730f45201 | ||
|
|
605acab31a | ||
|
|
ebca40640d | ||
|
|
a50a39a192 | ||
|
|
adc83f6dca | ||
|
|
bd0768a42a | ||
|
|
543d220bd4 | ||
|
|
44490e3ee1 | ||
|
|
4b2015eafd | ||
|
|
65005b4cd3 | ||
|
|
fae0d2c1f2 | ||
|
|
2c16a80113 | ||
|
|
44c6a76b09 | ||
|
|
37a2750e4f | ||
|
|
b5006a5404 | ||
|
|
3323690cbc | ||
|
|
1a50de508c | ||
|
|
b47f423907 | ||
|
|
d1b32a3b64 | ||
|
|
f87f6226aa | ||
|
|
cd576666fc | ||
|
|
6b1f13fd0f | ||
|
|
7db221e47e | ||
|
|
e5511b1920 | ||
|
|
0ca1e680db | ||
|
|
2e978c8776 | ||
|
|
31027b9240 | ||
|
|
1d0680ce95 | ||
|
|
997ef242a2 | ||
|
|
b869822c8b | ||
|
|
2d080580bd | ||
|
|
e3c65d9a34 | ||
|
|
818e35e71c | ||
|
|
ba751970af | ||
|
|
13fcbe139d | ||
|
|
5ea325afcc | ||
|
|
cf523b95be | ||
|
|
0f642a8397 | ||
|
|
b653567e3e | ||
|
|
85d23dde79 | ||
|
|
5e7bd7a36b |
6
.github/workflows/cibuild-setup-ubuntu.sh
vendored
6
.github/workflows/cibuild-setup-ubuntu.sh
vendored
@@ -5,9 +5,9 @@ set -ex
|
||||
PACKAGES=(
|
||||
git make autoconf automake autopoint pkg-config libtool libtool-bin
|
||||
gettext libssl-dev libdevmapper-dev libpopt-dev uuid-dev libsepol-dev
|
||||
libjson-c-dev libssh-dev libblkid-dev tar libargon2-0-dev libpwquality-dev
|
||||
sharutils dmsetup jq xxd expect keyutils netcat passwd openssh-client sshpass
|
||||
asciidoctor meson ninja-build
|
||||
libjson-c-dev libssh-dev libblkid-dev tar libargon2-dev libpwquality-dev
|
||||
sharutils dmsetup jq xxd expect keyutils netcat-openbsd passwd openssh-client
|
||||
sshpass asciidoctor meson ninja-build
|
||||
)
|
||||
|
||||
COMPILER="${COMPILER:?}"
|
||||
|
||||
7
.github/workflows/cibuild.yml
vendored
7
.github/workflows/cibuild.yml
vendored
@@ -4,8 +4,7 @@ on:
|
||||
branches:
|
||||
- 'main'
|
||||
- 'wip-luks2'
|
||||
- 'v2.3.x'
|
||||
- 'v2.4.x'
|
||||
- 'v2.*.x'
|
||||
paths-ignore:
|
||||
- 'docs/**'
|
||||
|
||||
@@ -17,11 +16,11 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
env:
|
||||
- { COMPILER: "gcc", COMPILER_VERSION: "11", RUN_SSH_PLUGIN_TEST: "1" }
|
||||
- { COMPILER: "gcc", COMPILER_VERSION: "14", RUN_SSH_PLUGIN_TEST: "1" }
|
||||
env: ${{ matrix.env }}
|
||||
steps:
|
||||
- name: Repository checkout
|
||||
uses: actions/checkout@v1
|
||||
uses: actions/checkout@v4
|
||||
- name: Ubuntu setup
|
||||
run: sudo -E .github/workflows/cibuild-setup-ubuntu.sh
|
||||
- name: Configure & Make
|
||||
|
||||
19
.github/workflows/codeql.yml
vendored
19
.github/workflows/codeql.yml
vendored
@@ -5,8 +5,7 @@ on:
|
||||
branches:
|
||||
- 'main'
|
||||
- 'wip-luks2'
|
||||
- 'v2.3.x'
|
||||
- 'v2.4.x'
|
||||
- 'v2.*.x'
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
@@ -30,21 +29,25 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
uses: github/codeql-action/init@v3
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
queries: +security-extended,security-and-quality
|
||||
config-file: .codeql-config.yml
|
||||
|
||||
- name: Install dependencies
|
||||
run: sudo -E .github/workflows/cibuild-setup-ubuntu.sh
|
||||
env: { COMPILER: "gcc", COMPILER_VERSION: "11", RUN_SSH_PLUGIN_TEST: "1" }
|
||||
run: |
|
||||
sudo -E .github/workflows/cibuild-setup-ubuntu.sh
|
||||
# Force autoconf for now, meson is broken in analysis step
|
||||
rm meson.build
|
||||
|
||||
env: { COMPILER: "gcc", COMPILER_VERSION: "14", RUN_SSH_PLUGIN_TEST: "1" }
|
||||
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v2
|
||||
uses: github/codeql-action/autobuild@v3
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v2
|
||||
uses: github/codeql-action/analyze@v3
|
||||
|
||||
4
.github/workflows/coverity.yml
vendored
4
.github/workflows/coverity.yml
vendored
@@ -12,12 +12,12 @@ jobs:
|
||||
if: github.repository == 'mbroz/cryptsetup'
|
||||
steps:
|
||||
- name: Repository checkout
|
||||
uses: actions/checkout@v1
|
||||
uses: actions/checkout@v4
|
||||
- name: Ubuntu setup
|
||||
run: sudo -E .github/workflows/cibuild-setup-ubuntu.sh
|
||||
env:
|
||||
COMPILER: "gcc"
|
||||
COMPILER_VERSION: "11"
|
||||
COMPILER_VERSION: "14"
|
||||
- name: Install Coverity
|
||||
run: |
|
||||
wget -q https://scan.coverity.com/download/cxx/linux64 --post-data "token=$TOKEN&project=mbroz/cryptsetup" -O cov-analysis-linux64.tar.gz
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -17,6 +17,7 @@ ABOUT-NLS
|
||||
aclocal.m4
|
||||
autom4te.cache/
|
||||
compile
|
||||
compile_commands.json
|
||||
config.guess
|
||||
config.h
|
||||
config.h.in
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
stages:
|
||||
- test
|
||||
- test-opal
|
||||
|
||||
.dump_kernel_log:
|
||||
.fail_if_coredump_generated:
|
||||
after_script:
|
||||
- sudo dmesg > /mnt/artifacts/dmesg.log
|
||||
- sudo journalctl > /mnt/artifacts/journalctl.log
|
||||
- '[ "$(ls -A /var/coredumps)" ] && exit 1 || true'
|
||||
|
||||
include:
|
||||
- local: .gitlab/ci/debian.yml
|
||||
- local: .gitlab/ci/fedora.yml
|
||||
- local: .gitlab/ci/rhel.yml
|
||||
- local: .gitlab/ci/fedora-opal.yml
|
||||
- local: .gitlab/ci/centos.yml
|
||||
- local: .gitlab/ci/annocheck.yml
|
||||
# - local: .gitlab/ci/annocheck.yml
|
||||
- local: .gitlab/ci/csmock.yml
|
||||
- local: .gitlab/ci/gitlab-shared-docker.yml
|
||||
- local: .gitlab/ci/compilation-various-disables.yml
|
||||
- local: .gitlab/ci/compilation-gcc.gitlab-ci.yml
|
||||
- local: .gitlab/ci/compilation-clang.gitlab-ci.yml
|
||||
- local: .gitlab/ci/compilation-spellcheck.yml
|
||||
- local: .gitlab/ci/alpinelinux.yml
|
||||
- local: .gitlab/ci/ubuntu-32bit.yml
|
||||
- local: .gitlab/ci/debian-i686.yml
|
||||
- local: .gitlab/ci/cifuzz.yml
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
.alpinelinux-dependencies:
|
||||
after_script:
|
||||
- sudo dmesg > /mnt/artifacts/dmesg.log
|
||||
- sudo cp /var/log/messages /mnt/artifacts/
|
||||
- '[ "$(ls -A /var/coredumps)" ] && exit 1 || true'
|
||||
variables:
|
||||
DISTRO: cryptsetup-alpine-edge
|
||||
extends:
|
||||
- .fail_if_coredump_generated
|
||||
before_script:
|
||||
- >
|
||||
sudo apk add
|
||||
lvm2-dev openssl1.1-compat-dev popt-dev util-linux-dev json-c-dev
|
||||
argon2-dev device-mapper which sharutils gettext gettext-dev automake
|
||||
lvm2-dev openssl-dev popt-dev util-linux-dev json-c-dev
|
||||
argon2-dev device-mapper which sharutils gettext-dev argp-standalone automake
|
||||
autoconf libtool build-base keyutils tar jq expect git asciidoctor
|
||||
# Be sure we have updated basic tools and system
|
||||
- sudo apk upgrade gcc binutils build-base musl
|
||||
- ./autogen.sh
|
||||
- ./configure --prefix=/usr --libdir=/lib --sbindir=/sbin --disable-static --enable-libargon2 --with-crypto_backend=openssl --disable-external-tokens --disable-ssh-token --enable-asciidoc
|
||||
|
||||
@@ -17,7 +19,7 @@ test-main-commit-job-alpinelinux:
|
||||
- .alpinelinux-dependencies
|
||||
tags:
|
||||
- libvirt
|
||||
- alpinelinux
|
||||
- cryptsetup-alpine-edge
|
||||
stage: test
|
||||
interruptible: true
|
||||
variables:
|
||||
@@ -38,7 +40,7 @@ test-mergerq-job-alpinelinux:
|
||||
- .alpinelinux-dependencies
|
||||
tags:
|
||||
- libvirt
|
||||
- alpinelinux
|
||||
- cryptsetup-alpine-edge
|
||||
stage: test
|
||||
interruptible: true
|
||||
variables:
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
test-main-commit-job-annocheck:
|
||||
extends:
|
||||
- .dump_kernel_log
|
||||
- .fail_if_coredump_generated
|
||||
tags:
|
||||
- libvirt
|
||||
- rhel9-annocheck
|
||||
- cryptsetup-rhel-9
|
||||
stage: test
|
||||
interruptible: true
|
||||
allow_failure: true
|
||||
variables:
|
||||
DISTRO: cryptsetup-rhel-9
|
||||
RUN_SSH_PLUGIN_TEST: "1"
|
||||
rules:
|
||||
- if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
|
||||
|
||||
32
.gitlab/ci/build_srpm
Executable file
32
.gitlab/ci/build_srpm
Executable file
@@ -0,0 +1,32 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
SAVED_PWD=$(pwd)
|
||||
GIT_DIR="$SAVED_PWD/upstream_git"
|
||||
SPEC="$GIT_DIR/misc/fedora/cryptsetup.spec"
|
||||
|
||||
rm -fr $GIT_DIR
|
||||
|
||||
git clone -q --depth 1 https://gitlab.com/cryptsetup/cryptsetup.git $GIT_DIR
|
||||
cd $GIT_DIR
|
||||
|
||||
GIT_COMMIT=$(git rev-parse --short=8 HEAD)
|
||||
[ -z "$GIT_COMMIT" ] && exit 1
|
||||
|
||||
sed -i "s/^AC_INIT.*/AC_INIT([cryptsetup],[$GIT_COMMIT])/" $GIT_DIR/configure.ac
|
||||
sed -i "s/^Version:.*/Version: $GIT_COMMIT/" $SPEC
|
||||
sed -i "s/%{version_no_tilde}/$GIT_COMMIT/" $SPEC
|
||||
sed -i "2i %global source_date_epoch_from_changelog 0" $SPEC
|
||||
sed -i "3i %define _unpackaged_files_terminate_build 0" $SPEC
|
||||
|
||||
./autogen.sh
|
||||
./configure
|
||||
make -j dist
|
||||
|
||||
rpmbuild --define "_sourcedir $GIT_DIR" --define "_srcrpmdir $SAVED_PWD" -bs $SPEC
|
||||
|
||||
cd $SAVED_PWD
|
||||
rm -fr $GIT_DIR
|
||||
|
||||
exit 0
|
||||
@@ -1,14 +1,16 @@
|
||||
.centos-openssl-backend:
|
||||
extends:
|
||||
- .dump_kernel_log
|
||||
- .fail_if_coredump_generated
|
||||
before_script:
|
||||
- sudo dnf clean all
|
||||
- >
|
||||
sudo dnf -y -q install
|
||||
autoconf automake device-mapper-devel gcc gettext-devel json-c-devel
|
||||
libblkid-devel libpwquality-devel libselinux-devel libssh-devel libtool
|
||||
libuuid-devel make popt-devel libsepol-devel nc openssh-clients passwd
|
||||
pkgconfig sharutils sshpass tar uuid-devel vim-common device-mapper
|
||||
expect gettext git jq keyutils openssl-devel openssl gem
|
||||
expect gettext git jq keyutils openssl-devel openssl gem swtpm swtpm-tools
|
||||
tpm2-tools
|
||||
- sudo gem install asciidoctor
|
||||
- sudo -E git clean -xdf
|
||||
- ./autogen.sh
|
||||
@@ -21,11 +23,13 @@ test-main-commit-centos-stream9:
|
||||
- .centos-openssl-backend
|
||||
tags:
|
||||
- libvirt
|
||||
- centos-stream9
|
||||
- cryptsetup-centos-stream-9
|
||||
stage: test
|
||||
interruptible: true
|
||||
variables:
|
||||
DISTRO: cryptsetup-centos-stream-9
|
||||
RUN_SSH_PLUGIN_TEST: "1"
|
||||
RUN_KEYRING_TRUSTED_TEST: "1"
|
||||
rules:
|
||||
- if: $RUN_SYSTEMD_PLUGIN_TEST != null
|
||||
when: never
|
||||
@@ -42,11 +46,59 @@ test-mergerq-centos-stream9:
|
||||
- .centos-openssl-backend
|
||||
tags:
|
||||
- libvirt
|
||||
- centos-stream9
|
||||
- cryptsetup-centos-stream-9
|
||||
stage: test
|
||||
interruptible: true
|
||||
variables:
|
||||
DISTRO: cryptsetup-centos-stream-9
|
||||
RUN_SSH_PLUGIN_TEST: "1"
|
||||
RUN_KEYRING_TRUSTED_TEST: "1"
|
||||
rules:
|
||||
- if: $RUN_SYSTEMD_PLUGIN_TEST != null
|
||||
when: never
|
||||
- if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
|
||||
when: never
|
||||
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
||||
script:
|
||||
- make -j
|
||||
- make -j -C tests check-programs
|
||||
- sudo -E make check
|
||||
|
||||
test-main-commit-centos-stream10:
|
||||
extends:
|
||||
- .centos-openssl-backend
|
||||
tags:
|
||||
- libvirt
|
||||
- cryptsetup-centos-stream-10
|
||||
stage: test
|
||||
interruptible: true
|
||||
variables:
|
||||
DISTRO: cryptsetup-centos-stream-10
|
||||
RUN_SSH_PLUGIN_TEST: "1"
|
||||
RUN_KEYRING_TRUSTED_TEST: "1"
|
||||
rules:
|
||||
- if: $RUN_SYSTEMD_PLUGIN_TEST != null
|
||||
when: never
|
||||
- if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
|
||||
when: never
|
||||
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /v2\..\.x$/
|
||||
script:
|
||||
- make -j
|
||||
- make -j -C tests check-programs
|
||||
- sudo -E make check
|
||||
|
||||
test-mergerq-centos-stream10:
|
||||
extends:
|
||||
- .centos-openssl-backend
|
||||
tags:
|
||||
- libvirt
|
||||
- cryptsetup-centos-stream-10
|
||||
stage: test
|
||||
interruptible: true
|
||||
variables:
|
||||
DISTRO: cryptsetup-centos-stream-10
|
||||
RUN_SSH_PLUGIN_TEST: "1"
|
||||
RUN_KEYRING_TRUSTED_TEST: "1"
|
||||
rules:
|
||||
- if: $RUN_SYSTEMD_PLUGIN_TEST != null
|
||||
when: never
|
||||
|
||||
@@ -5,7 +5,7 @@ set -ex
|
||||
PACKAGES=(
|
||||
git make autoconf automake autopoint pkg-config libtool libtool-bin
|
||||
gettext libssl-dev libdevmapper-dev libpopt-dev uuid-dev libsepol-dev
|
||||
libjson-c-dev libssh-dev libblkid-dev tar libargon2-0-dev libpwquality-dev
|
||||
libjson-c-dev libssh-dev libblkid-dev tar libargon2-dev libpwquality-dev
|
||||
sharutils dmsetup jq xxd expect keyutils netcat-openbsd passwd openssh-client
|
||||
sshpass asciidoctor
|
||||
)
|
||||
@@ -13,9 +13,12 @@ PACKAGES=(
|
||||
COMPILER="${COMPILER:?}"
|
||||
COMPILER_VERSION="${COMPILER_VERSION:?}"
|
||||
|
||||
grep -E '^deb' /etc/apt/sources.list > /etc/apt/sources.list~
|
||||
sed -Ei 's/^deb /deb-src /' /etc/apt/sources.list~
|
||||
cat /etc/apt/sources.list~ >> /etc/apt/sources.list
|
||||
sed -i 's/^Types: deb$/Types: deb deb-src/' /etc/apt/sources.list.d/ubuntu.sources
|
||||
|
||||
# use this on older Ubuntu
|
||||
# grep -E '^deb' /etc/apt/sources.list > /etc/apt/sources.list~
|
||||
# sed -Ei 's/^deb /deb-src /' /etc/apt/sources.list~
|
||||
# cat /etc/apt/sources.list~ >> /etc/apt/sources.list
|
||||
|
||||
apt-get -y update --fix-missing
|
||||
DEBIAN_FRONTEND=noninteractive apt-get -yq install software-properties-common wget lsb-release
|
||||
@@ -28,7 +31,7 @@ if [[ $COMPILER == "gcc" ]]; then
|
||||
PACKAGES+=(gcc-$COMPILER_VERSION)
|
||||
elif [[ $COMPILER == "clang" ]]; then
|
||||
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add -
|
||||
add-apt-repository "deb http://apt.llvm.org/${RELEASE}/ llvm-toolchain-${RELEASE}-${COMPILER_VERSION} main"
|
||||
add-apt-repository -n "deb http://apt.llvm.org/${RELEASE}/ llvm-toolchain-${RELEASE}-${COMPILER_VERSION} main"
|
||||
|
||||
# scan-build
|
||||
PACKAGES+=(clang-tools-$COMPILER_VERSION clang-$COMPILER_VERSION lldb-$COMPILER_VERSION lld-$COMPILER_VERSION clangd-$COMPILER_VERSION)
|
||||
@@ -37,14 +40,8 @@ else
|
||||
exit 1
|
||||
fi
|
||||
|
||||
apt-get -y update --fix-missing
|
||||
#apt-get -y update --fix-missing
|
||||
(r=3;while ! apt-get -y update --fix-missing ; do ((--r))||exit;sleep 5;echo "Retrying";done)
|
||||
|
||||
DEBIAN_FRONTEND=noninteractive apt-get -yq install "${PACKAGES[@]}"
|
||||
apt-get -y build-dep cryptsetup
|
||||
|
||||
echo "====================== VERSIONS ==================="
|
||||
if [[ $COMPILER == "clang" ]]; then
|
||||
echo "Using scan-build${COMPILER_VERSION:+-$COMPILER_VERSION}"
|
||||
fi
|
||||
|
||||
${COMPILER}-$COMPILER_VERSION -v
|
||||
echo "====================== END VERSIONS ==================="
|
||||
|
||||
@@ -4,27 +4,85 @@ test-clang-compilation:
|
||||
script:
|
||||
- export CFLAGS="-Wall -Werror"
|
||||
- ./autogen.sh
|
||||
- $CC --version
|
||||
- ./configure
|
||||
- make -j
|
||||
- make -j check-programs
|
||||
|
||||
test-clang-Wall-script:
|
||||
test-clang-Wall-script-ubuntu:
|
||||
extends:
|
||||
- .gitlab-shared-clang
|
||||
script:
|
||||
- export CFLAGS="-g -O0"
|
||||
- export CC="$CI_PROJECT_DIR/.gitlab/ci/clang-Wall"
|
||||
- ./autogen.sh
|
||||
- $CC --version
|
||||
- ./configure
|
||||
- make -j CFLAGS="-g -O0 -Werror"
|
||||
- make -j CFLAGS="-g -O0 -Werror" check-programs
|
||||
|
||||
test-scan-build:
|
||||
test-clang-Wall-script-alpine:
|
||||
extends:
|
||||
- .gitlab-shared-clang-alpine
|
||||
allow_failure: true
|
||||
script:
|
||||
- export CFLAGS="-g -O0"
|
||||
- export CC="$CI_PROJECT_DIR/.gitlab/ci/clang-Wall"
|
||||
- ./autogen.sh
|
||||
- $CC --version
|
||||
- ./configure
|
||||
- make -j CFLAGS="-g -O0 -Werror"
|
||||
- make -j CFLAGS="-g -O0 -Werror" check-programs
|
||||
|
||||
test-scan-build-ubuntu:
|
||||
extends:
|
||||
- .gitlab-shared-clang
|
||||
script:
|
||||
- ./autogen.sh
|
||||
- echo "scan-build${COMPILER_VERSION:+-$COMPILER_VERSION}"
|
||||
- scan-build${COMPILER_VERSION:+-$COMPILER_VERSION} -V ./configure CFLAGS="-g -O0"
|
||||
- make clean
|
||||
- scan-build${COMPILER_VERSION:+-$COMPILER_VERSION} --status-bugs -maxloop 10 make -j
|
||||
- scan-build${COMPILER_VERSION:+-$COMPILER_VERSION} --status-bugs -maxloop 10 make -j check-programs
|
||||
|
||||
test-scan-build-alpine:
|
||||
extends:
|
||||
- .gitlab-shared-clang-alpine
|
||||
allow_failure: true
|
||||
script:
|
||||
- ./autogen.sh
|
||||
- echo "scan-build${COMPILER_VERSION:+-$COMPILER_VERSION}"
|
||||
- scan-build${COMPILER_VERSION:+-$COMPILER_VERSION} -V ./configure CFLAGS="-g -O0"
|
||||
- make clean
|
||||
- scan-build${COMPILER_VERSION:+-$COMPILER_VERSION} --status-bugs -maxloop 10 make -j
|
||||
- scan-build${COMPILER_VERSION:+-$COMPILER_VERSION} --status-bugs -maxloop 10 make -j check-programs
|
||||
|
||||
test-scan-build-backends:
|
||||
extends:
|
||||
- .gitlab-shared-clang
|
||||
parallel:
|
||||
matrix:
|
||||
- BACKENDS: [
|
||||
"openssl",
|
||||
"gcrypt",
|
||||
"nss",
|
||||
"kernel",
|
||||
"nettle",
|
||||
"mbedtls"
|
||||
]
|
||||
rules:
|
||||
- if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
|
||||
when: never
|
||||
- if: $CI_PIPELINE_SOURCE == "merge_request_event" || $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /v2\..\.x$/
|
||||
changes:
|
||||
- lib/crypto_backend/*
|
||||
script:
|
||||
- DEBIAN_FRONTEND=noninteractive apt-get -yq install libgcrypt20-dev libnss3-dev nettle-dev libmbedtls-dev
|
||||
- ./autogen.sh
|
||||
- echo "Configuring with crypto backend $BACKENDS"
|
||||
- echo "scan-build${COMPILER_VERSION:+-$COMPILER_VERSION}"
|
||||
- scan-build${COMPILER_VERSION:+-$COMPILER_VERSION} -V ./configure CFLAGS="-g -O0" --with-crypto_backend=$BACKENDS
|
||||
- make clean
|
||||
- scan-build${COMPILER_VERSION:+-$COMPILER_VERSION} --status-bugs -maxloop 10 make -j
|
||||
- scan-build${COMPILER_VERSION:+-$COMPILER_VERSION} --status-bugs -maxloop 10 make -j check-programs
|
||||
- ./tests/vectors-test
|
||||
|
||||
@@ -4,27 +4,82 @@ test-gcc-compilation:
|
||||
script:
|
||||
- export CFLAGS="-Wall -Werror"
|
||||
- ./autogen.sh
|
||||
- $CC --version
|
||||
- ./configure
|
||||
- make -j
|
||||
- make -j check-programs
|
||||
|
||||
test-gcc-Wall-script:
|
||||
test-gcc-Wall-script-ubuntu:
|
||||
extends:
|
||||
- .gitlab-shared-gcc
|
||||
script:
|
||||
- export CFLAGS="-g -O0"
|
||||
- export CC="$CI_PROJECT_DIR/.gitlab/ci/gcc-Wall"
|
||||
- ./autogen.sh
|
||||
- $CC --version
|
||||
- ./configure
|
||||
- make -j CFLAGS="-g -O0 -Werror"
|
||||
- make -j CFLAGS="-g -O0 -Werror" check-programs
|
||||
|
||||
test-gcc-fanalyzer:
|
||||
test-gcc-Wall-script-alpine:
|
||||
extends:
|
||||
- .gitlab-shared-gcc-alpine
|
||||
allow_failure: true
|
||||
script:
|
||||
- export CFLAGS="-g -O0"
|
||||
- export CC="$CI_PROJECT_DIR/.gitlab/ci/gcc-Wall"
|
||||
- ./autogen.sh
|
||||
- $CC --version
|
||||
- ./configure
|
||||
- make -j CFLAGS="-g -O0 -Werror"
|
||||
- make -j CFLAGS="-g -O0 -Werror" check-programs
|
||||
|
||||
test-gcc-fanalyzer-ubuntu:
|
||||
extends:
|
||||
- .gitlab-shared-gcc
|
||||
script:
|
||||
- export CFLAGS="-Wall -Werror -g -O0 -fanalyzer -fdiagnostics-path-format=separate-events"
|
||||
- ./autogen.sh
|
||||
- ./configure
|
||||
- $CC --version
|
||||
- ./configure CFLAGS="-Wall -Werror -g -O0 -fanalyzer -fdiagnostics-path-format=separate-events" --host=x86_64
|
||||
- make -j
|
||||
- make -j check-programs
|
||||
|
||||
test-gcc-fanalyzer-alpine:
|
||||
extends:
|
||||
- .gitlab-shared-gcc-alpine
|
||||
allow_failure: true
|
||||
script:
|
||||
- ./autogen.sh
|
||||
- $CC --version
|
||||
- ./configure CFLAGS="-Wall -Werror -g -O0 -fanalyzer -fdiagnostics-path-format=separate-events -Wno-analyzer-fd-leak" --host=x86_64
|
||||
- make -j
|
||||
- make -j check-programs
|
||||
|
||||
test-gcc-fanalyzer-backends:
|
||||
extends:
|
||||
- .gitlab-shared-gcc
|
||||
parallel:
|
||||
matrix:
|
||||
- BACKENDS: [
|
||||
"openssl",
|
||||
"gcrypt",
|
||||
"nss",
|
||||
"kernel",
|
||||
"nettle",
|
||||
"mbedtls"
|
||||
]
|
||||
rules:
|
||||
- if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
|
||||
when: never
|
||||
- if: $CI_PIPELINE_SOURCE == "merge_request_event" || $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /v2\..\.x$/
|
||||
changes:
|
||||
- lib/crypto_backend/*
|
||||
script:
|
||||
- DEBIAN_FRONTEND=noninteractive apt-get -yq install libgcrypt20-dev libnss3-dev nettle-dev libmbedtls-dev
|
||||
- ./autogen.sh
|
||||
- $CC --version
|
||||
- echo "Configuring with crypto backend $BACKENDS"
|
||||
- ./configure CFLAGS="-Wall -Werror -g -O0 -fanalyzer -fdiagnostics-path-format=separate-events" --host=x86_64 --with-crypto_backend=$BACKENDS
|
||||
- make -j
|
||||
- make -j check-programs
|
||||
- ./tests/vectors-test
|
||||
|
||||
20
.gitlab/ci/compilation-spellcheck.yml
Normal file
20
.gitlab/ci/compilation-spellcheck.yml
Normal file
@@ -0,0 +1,20 @@
|
||||
test-run-spellcheck:
|
||||
image: ubuntu:noble
|
||||
tags:
|
||||
- gitlab-org-docker
|
||||
stage: test
|
||||
interruptible: true
|
||||
rules:
|
||||
- if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
|
||||
when: never
|
||||
- if: $CI_PIPELINE_SOURCE == "merge_request_event" || $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /v2\..\.x$/
|
||||
artifacts:
|
||||
name: "spellcheck-$CI_COMMIT_REF_NAME"
|
||||
paths:
|
||||
- _spellcheck
|
||||
before_script:
|
||||
- apt-get -y update --fix-missing
|
||||
- apt-get -y install git lintian codespell
|
||||
script:
|
||||
- echo "Running spellcheck"
|
||||
- .gitlab/ci/spellcheck
|
||||
@@ -11,7 +11,8 @@ test-gcc-disable-compiles:
|
||||
"kernel_crypto",
|
||||
"udev",
|
||||
"internal-argon2",
|
||||
"blkid"
|
||||
"blkid",
|
||||
"hw-opal"
|
||||
]
|
||||
artifacts:
|
||||
name: "meson-build-logs-$CI_COMMIT_REF_NAME"
|
||||
|
||||
@@ -1,23 +1,36 @@
|
||||
.dnf-csmock:
|
||||
variables:
|
||||
DISTRO: cryptsetup-fedora-rawhide
|
||||
DISK_SIZE: 20
|
||||
extends:
|
||||
- .fail_if_coredump_generated
|
||||
before_script:
|
||||
- >
|
||||
sudo dnf -y -q install
|
||||
autoconf automake device-mapper-devel gcc gettext-devel json-c-devel
|
||||
libblkid-devel libpwquality-devel libselinux-devel
|
||||
libssh-devel libtool libuuid-devel make popt-devel
|
||||
libsepol-devel.x86_64 pkgconfig tar uuid-devel git
|
||||
openssl-devel asciidoctor meson ninja-build
|
||||
rpm-build csmock
|
||||
|
||||
test-commit-job-csmock:
|
||||
extends:
|
||||
- .dump_kernel_log
|
||||
- .dnf-csmock
|
||||
tags:
|
||||
- libvirt
|
||||
- rhel9-csmock
|
||||
- cryptsetup-fedora-rawhide
|
||||
stage: test
|
||||
interruptible: true
|
||||
allow_failure: true
|
||||
variables:
|
||||
RUN_SSH_PLUGIN_TEST: "1"
|
||||
rules:
|
||||
- if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
|
||||
when: never
|
||||
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /v2\..\.x$/ || $CI_PIPELINE_SOURCE == "merge_request_event"
|
||||
script:
|
||||
- sudo /opt/run-csmock.sh
|
||||
- .gitlab/ci/build_srpm
|
||||
- .gitlab/ci/run_csmock
|
||||
artifacts:
|
||||
# Upload artifacts when a crash makes the job fail.
|
||||
when: always
|
||||
paths:
|
||||
- cryptsetup-csmock-results.tar.xz
|
||||
- cryptsetup-csmock-results
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
test-mergerq-job-ubuntu-32bit:
|
||||
test-mergerq-job-debian-i686:
|
||||
extends:
|
||||
- .debian-prep
|
||||
tags:
|
||||
- libvirt
|
||||
- ubuntu-bionic-32bit
|
||||
- cryptsetup-debian-12i686
|
||||
stage: test
|
||||
interruptible: true
|
||||
variables:
|
||||
DISTRO: cryptsetup-debian-12i686
|
||||
RUN_SSH_PLUGIN_TEST: "1"
|
||||
rules:
|
||||
- if: $RUN_SYSTEMD_PLUGIN_TEST != null
|
||||
@@ -19,15 +20,16 @@ test-mergerq-job-ubuntu-32bit:
|
||||
- make -j -C tests check-programs
|
||||
- sudo -E make check
|
||||
|
||||
test-main-commit-job-ubuntu-32bit:
|
||||
test-main-commit-job-debian-i686:
|
||||
extends:
|
||||
- .debian-prep
|
||||
tags:
|
||||
- libvirt
|
||||
- ubuntu-bionic-32bit
|
||||
- cryptsetup-debian-12i686
|
||||
stage: test
|
||||
interruptible: true
|
||||
variables:
|
||||
DISTRO: cryptsetup-debian-12i686
|
||||
RUN_SSH_PLUGIN_TEST: "1"
|
||||
rules:
|
||||
- if: $RUN_SYSTEMD_PLUGIN_TEST != null
|
||||
@@ -1,18 +1,16 @@
|
||||
.debian-prep:
|
||||
extends:
|
||||
- .dump_kernel_log
|
||||
- .fail_if_coredump_generated
|
||||
before_script:
|
||||
- sudo apt-get -y update
|
||||
- >
|
||||
[ -z "$RUN_SYSTEMD_PLUGIN_TEST" ] ||
|
||||
sudo apt-get -y install -y -qq swtpm meson ninja-build python3-jinja2
|
||||
gperf libcap-dev libtss2-dev libmount-dev swtpm-tools
|
||||
- >
|
||||
sudo apt-get -y install -y -qq git gcc make autoconf automake autopoint
|
||||
pkgconf libtool libtool-bin gettext libssl-dev libdevmapper-dev
|
||||
libpopt-dev uuid-dev libsepol-dev libjson-c-dev libssh-dev libblkid-dev
|
||||
tar libargon2-0-dev libpwquality-dev sharutils dmsetup jq xxd expect
|
||||
tar libargon2-dev libpwquality-dev sharutils dmsetup jq xxd expect
|
||||
keyutils netcat-openbsd passwd openssh-client sshpass asciidoctor
|
||||
swtpm meson ninja-build python3-jinja2 gperf libcap-dev libtss2-dev
|
||||
libmount-dev swtpm-tools tpm2-tools
|
||||
- sudo apt-get -y build-dep cryptsetup
|
||||
- sudo -E git clean -xdf
|
||||
- ./autogen.sh
|
||||
@@ -23,11 +21,13 @@ test-mergerq-job-debian:
|
||||
- .debian-prep
|
||||
tags:
|
||||
- libvirt
|
||||
- debian12
|
||||
- cryptsetup-debian-unstable
|
||||
stage: test
|
||||
interruptible: true
|
||||
variables:
|
||||
DISTRO: cryptsetup-debian-unstable
|
||||
RUN_SSH_PLUGIN_TEST: "1"
|
||||
RUN_KEYRING_TRUSTED_TEST: "1"
|
||||
rules:
|
||||
- if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
|
||||
when: never
|
||||
@@ -42,11 +42,55 @@ test-main-commit-job-debian:
|
||||
- .debian-prep
|
||||
tags:
|
||||
- libvirt
|
||||
- debian12
|
||||
- cryptsetup-debian-unstable
|
||||
stage: test
|
||||
interruptible: true
|
||||
variables:
|
||||
DISTRO: cryptsetup-debian-unstable
|
||||
RUN_SSH_PLUGIN_TEST: "1"
|
||||
RUN_KEYRING_TRUSTED_TEST: "1"
|
||||
rules:
|
||||
- if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
|
||||
when: never
|
||||
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /v2\..\.x$/
|
||||
script:
|
||||
- make -j
|
||||
- make -j -C tests check-programs
|
||||
- sudo -E make check
|
||||
|
||||
test-mergerq-job-debian12:
|
||||
extends:
|
||||
- .debian-prep
|
||||
tags:
|
||||
- libvirt
|
||||
- cryptsetup-debian-12
|
||||
stage: test
|
||||
interruptible: true
|
||||
variables:
|
||||
DISTRO: cryptsetup-debian-12
|
||||
RUN_SSH_PLUGIN_TEST: "1"
|
||||
RUN_KEYRING_TRUSTED_TEST: "1"
|
||||
rules:
|
||||
- if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
|
||||
when: never
|
||||
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
||||
script:
|
||||
- make -j
|
||||
- make -j -C tests check-programs
|
||||
- sudo -E make check
|
||||
|
||||
test-main-commit-job-debian12:
|
||||
extends:
|
||||
- .debian-prep
|
||||
tags:
|
||||
- libvirt
|
||||
- cryptsetup-debian-12
|
||||
stage: test
|
||||
interruptible: true
|
||||
variables:
|
||||
DISTRO: cryptsetup-debian-12
|
||||
RUN_SSH_PLUGIN_TEST: "1"
|
||||
RUN_KEYRING_TRUSTED_TEST: "1"
|
||||
rules:
|
||||
- if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
|
||||
when: never
|
||||
@@ -62,11 +106,13 @@ test-mergerq-job-debian-meson:
|
||||
- .debian-prep
|
||||
tags:
|
||||
- libvirt
|
||||
- debian12
|
||||
- cryptsetup-debian-unstable
|
||||
stage: test
|
||||
interruptible: true
|
||||
variables:
|
||||
DISTRO: cryptsetup-debian-unstable
|
||||
RUN_SSH_PLUGIN_TEST: "1"
|
||||
RUN_KEYRING_TRUSTED_TEST: "1"
|
||||
rules:
|
||||
- if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
|
||||
when: never
|
||||
@@ -82,11 +128,57 @@ test-main-commit-job-debian-meson:
|
||||
- .debian-prep
|
||||
tags:
|
||||
- libvirt
|
||||
- debian12
|
||||
- cryptsetup-debian-unstable
|
||||
stage: test
|
||||
interruptible: true
|
||||
variables:
|
||||
DISTRO: cryptsetup-debian-unstable
|
||||
RUN_SSH_PLUGIN_TEST: "1"
|
||||
RUN_KEYRING_TRUSTED_TEST: "1"
|
||||
rules:
|
||||
- if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
|
||||
when: never
|
||||
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /v2\..\.x$/
|
||||
script:
|
||||
- sudo apt-get -y install -y -qq meson ninja-build
|
||||
- meson setup build
|
||||
- ninja -C build
|
||||
- cd build && sudo -E meson test --verbose --print-errorlogs
|
||||
|
||||
test-mergerq-job-debian12-meson:
|
||||
extends:
|
||||
- .debian-prep
|
||||
tags:
|
||||
- libvirt
|
||||
- cryptsetup-debian-12
|
||||
stage: test
|
||||
interruptible: true
|
||||
variables:
|
||||
DISTRO: cryptsetup-debian-12
|
||||
RUN_SSH_PLUGIN_TEST: "1"
|
||||
RUN_KEYRING_TRUSTED_TEST: "1"
|
||||
rules:
|
||||
- if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
|
||||
when: never
|
||||
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
||||
script:
|
||||
- sudo apt-get -y install -y -qq meson ninja-build
|
||||
- meson setup build
|
||||
- ninja -C build
|
||||
- cd build && sudo -E meson test --verbose --print-errorlogs
|
||||
|
||||
test-main-commit-job-debian12-meson:
|
||||
extends:
|
||||
- .debian-prep
|
||||
tags:
|
||||
- libvirt
|
||||
- cryptsetup-debian-12
|
||||
stage: test
|
||||
interruptible: true
|
||||
variables:
|
||||
DISTRO: cryptsetup-debian-12
|
||||
RUN_SSH_PLUGIN_TEST: "1"
|
||||
RUN_KEYRING_TRUSTED_TEST: "1"
|
||||
rules:
|
||||
- if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
|
||||
when: never
|
||||
|
||||
145
.gitlab/ci/fedora-opal.yml
Normal file
145
.gitlab/ci/fedora-opal.yml
Normal file
@@ -0,0 +1,145 @@
|
||||
.opal-template-fedora:
|
||||
extends:
|
||||
- .dnf-openssl-backend
|
||||
tags:
|
||||
- libvirt
|
||||
- cryptsetup-fedora-rawhide
|
||||
stage: test-opal
|
||||
interruptible: false
|
||||
variables:
|
||||
OPAL2_DEV: "/dev/nvme0n1"
|
||||
OPAL2_PSID_FILE: "/home/gitlab-runner/psid.txt"
|
||||
VOLATILE: 1
|
||||
script:
|
||||
- sudo dnf install -y -q nvme-cli
|
||||
- sudo nvme list
|
||||
- make -j
|
||||
- make -j -C tests check-programs
|
||||
- sudo -E make check TESTS="00modules-test compat-test-opal"
|
||||
|
||||
# Samsung SSD 980 500GB (on tiber machine)
|
||||
test-commit-rawhide-samsung980:
|
||||
rules:
|
||||
- if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
|
||||
when: never
|
||||
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /v2\..\.x$/
|
||||
extends:
|
||||
- .opal-template-fedora
|
||||
tags:
|
||||
- tiber
|
||||
resource_group: samsung980-on-tiber
|
||||
interruptible: false
|
||||
variables:
|
||||
PCI_PASSTHROUGH_VENDOR_ID: "144d"
|
||||
PCI_PASSTHROUGH_DEVICE_ID: "a809"
|
||||
|
||||
test-mergerq-rawhide-samsung980:
|
||||
rules:
|
||||
- if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
|
||||
when: never
|
||||
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
||||
extends:
|
||||
- .opal-template-fedora
|
||||
tags:
|
||||
- tiber
|
||||
resource_group: samsung980-on-tiber
|
||||
interruptible: false
|
||||
variables:
|
||||
PCI_PASSTHROUGH_VENDOR_ID: "144d"
|
||||
PCI_PASSTHROUGH_DEVICE_ID: "a809"
|
||||
|
||||
# WD PC SN740 SDDQNQD-512G-1014 (on tiber machine)
|
||||
# Disabled on 2025-03-20, seems broken
|
||||
#test-commit-rawhide-sn740:
|
||||
# rules:
|
||||
# - if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
|
||||
# when: never
|
||||
# - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /v2\..\.x$/
|
||||
# extends:
|
||||
# - .opal-template-fedora
|
||||
# tags:
|
||||
# - tiber
|
||||
# resource_group: sn740-on-tiber
|
||||
# interruptible: false
|
||||
# variables:
|
||||
# PCI_PASSTHROUGH_VENDOR_ID: "15b7"
|
||||
# PCI_PASSTHROUGH_DEVICE_ID: "5017"
|
||||
#
|
||||
#test-mergerq-rawhide-sn740:
|
||||
# rules:
|
||||
# - if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
|
||||
# when: never
|
||||
# - if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
||||
# extends:
|
||||
# - .opal-template-fedora
|
||||
# tags:
|
||||
# - tiber
|
||||
# resource_group: sn740-on-tiber
|
||||
# interruptible: false
|
||||
# variables:
|
||||
# PCI_PASSTHROUGH_VENDOR_ID: "15b7"
|
||||
# PCI_PASSTHROUGH_DEVICE_ID: "5017"
|
||||
|
||||
# Samsung SSD 980 PRO 1TB (on trantor machine)
|
||||
test-commit-rawhide-samsung980pro:
|
||||
rules:
|
||||
- if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
|
||||
when: never
|
||||
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /v2\..\.x$/
|
||||
extends:
|
||||
- .opal-template-fedora
|
||||
tags:
|
||||
- trantor
|
||||
resource_group: samsung980pro-on-trantor
|
||||
interruptible: false
|
||||
variables:
|
||||
PCI_PASSTHROUGH_VENDOR_ID: "144d"
|
||||
PCI_PASSTHROUGH_DEVICE_ID: "a80a"
|
||||
|
||||
test-mergerq-rawhide-samsung980pro:
|
||||
rules:
|
||||
- if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
|
||||
when: never
|
||||
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
||||
extends:
|
||||
- .opal-template-fedora
|
||||
tags:
|
||||
- trantor
|
||||
resource_group: samsung980pro-on-trantor
|
||||
interruptible: false
|
||||
variables:
|
||||
PCI_PASSTHROUGH_VENDOR_ID: "144d"
|
||||
PCI_PASSTHROUGH_DEVICE_ID: "a80a"
|
||||
|
||||
# # UMIS RPETJ256MGE2MDQ (on tiber machine)
|
||||
# test-commit-rawhide-umis:
|
||||
# rules:
|
||||
# - if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
|
||||
# when: never
|
||||
# - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /v2\..\.x$/
|
||||
# extends:
|
||||
# - .opal-template-fedora
|
||||
# tags:
|
||||
# - tiber
|
||||
# resource_group: umis-on-tiber
|
||||
# stage: test
|
||||
# interruptible: false
|
||||
# variables:
|
||||
# PCI_PASSTHROUGH_VENDOR_ID: "1cc4"
|
||||
# PCI_PASSTHROUGH_DEVICE_ID: "6302"
|
||||
#
|
||||
# test-mergerq-rawhide-umis:
|
||||
# rules:
|
||||
# - if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
|
||||
# when: never
|
||||
# - if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
||||
# extends:
|
||||
# - .opal-template-fedora
|
||||
# tags:
|
||||
# - tiber
|
||||
# resource_group: umis-on-tiber
|
||||
# stage: test
|
||||
# interruptible: false
|
||||
# variables:
|
||||
# PCI_PASSTHROUGH_VENDOR_ID: "1cc4"
|
||||
# PCI_PASSTHROUGH_DEVICE_ID: "6302"
|
||||
@@ -1,20 +1,19 @@
|
||||
.dnf-openssl-backend:
|
||||
extends:
|
||||
- .dump_kernel_log
|
||||
before_script:
|
||||
- >
|
||||
[ -z "$RUN_SYSTEMD_PLUGIN_TEST" ] ||
|
||||
sudo dnf -y -q install
|
||||
swtpm meson ninja-build python3-jinja2 gperf libcap-devel tpm2-tss-devel
|
||||
libmount-devel swtpm-tools
|
||||
- >
|
||||
sudo dnf -y -q install
|
||||
variables:
|
||||
DISTRO: cryptsetup-fedora-rawhide
|
||||
PKGS: >-
|
||||
autoconf automake device-mapper-devel gcc gettext-devel json-c-devel
|
||||
libargon2-devel libblkid-devel libpwquality-devel libselinux-devel
|
||||
libssh-devel libtool libuuid-devel make popt-devel
|
||||
libsepol-devel.x86_64 netcat openssh-clients passwd pkgconfig sharutils
|
||||
sshpass tar uuid-devel vim-common device-mapper expect gettext git jq
|
||||
keyutils openssl-devel openssl asciidoctor
|
||||
keyutils openssl-devel openssl asciidoctor swtpm meson ninja-build
|
||||
python3-jinja2 gperf libcap-devel tpm2-tss-devel libmount-devel swtpm-tools
|
||||
extends:
|
||||
- .fail_if_coredump_generated
|
||||
before_script:
|
||||
- sudo dnf clean all
|
||||
- (r=3;while ! sudo dnf -y -q install $PKGS ; do ((--r))||exit;sleep 5;echo "Retrying";done)
|
||||
- sudo -E git clean -xdf
|
||||
- ./autogen.sh
|
||||
- ./configure --enable-fips --enable-pwquality --enable-libargon2 --with-crypto_backend=openssl --enable-asciidoc
|
||||
@@ -24,12 +23,14 @@ test-main-commit-job-rawhide:
|
||||
- .dnf-openssl-backend
|
||||
tags:
|
||||
- libvirt
|
||||
- fedora-rawhide
|
||||
- cryptsetup-fedora-rawhide
|
||||
stage: test
|
||||
interruptible: true
|
||||
allow_failure: true
|
||||
variables:
|
||||
RUN_SSH_PLUGIN_TEST: "1"
|
||||
RUN_KEYRING_TRUSTED_TEST: "1"
|
||||
RUN_SYSTEMD_PLUGIN_TEST: "1"
|
||||
rules:
|
||||
- if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
|
||||
when: never
|
||||
@@ -44,12 +45,14 @@ test-mergerq-job-rawhide:
|
||||
- .dnf-openssl-backend
|
||||
tags:
|
||||
- libvirt
|
||||
- fedora-rawhide
|
||||
- cryptsetup-fedora-rawhide
|
||||
stage: test
|
||||
interruptible: true
|
||||
allow_failure: true
|
||||
variables:
|
||||
RUN_SSH_PLUGIN_TEST: "1"
|
||||
RUN_KEYRING_TRUSTED_TEST: "1"
|
||||
RUN_SYSTEMD_PLUGIN_TEST: "1"
|
||||
rules:
|
||||
- if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
|
||||
when: never
|
||||
|
||||
@@ -36,7 +36,8 @@ EXTRA="-Wextra \
|
||||
-Wmaybe-uninitialized \
|
||||
-Wvla \
|
||||
-Wformat-overflow \
|
||||
-Wformat-truncation"
|
||||
-Wformat-truncation \
|
||||
-Wstringop-overread"
|
||||
|
||||
exec $GCC $PEDANTIC $CONVERSION \
|
||||
-Wall $Wuninitialized \
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
.gitlab-shared-docker:
|
||||
image: ubuntu:lunar
|
||||
# Ubuntu
|
||||
.gitlab-shared-docker-ubuntu:
|
||||
image: ubuntu:noble
|
||||
tags:
|
||||
- gitlab-org-docker
|
||||
stage: test
|
||||
@@ -13,18 +14,48 @@
|
||||
- export CC="${COMPILER}${COMPILER_VERSION:+-$COMPILER_VERSION}"
|
||||
- export CXX="${COMPILER}++${COMPILER_VERSION:+-$COMPILER_VERSION}"
|
||||
|
||||
# Alpine
|
||||
.gitlab-shared-docker-alpine:
|
||||
image: alpine:latest
|
||||
tags:
|
||||
- gitlab-org-docker
|
||||
stage: test
|
||||
interruptible: true
|
||||
rules:
|
||||
- if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
|
||||
when: never
|
||||
- if: $CI_PIPELINE_SOURCE == "merge_request_event" || $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /v2\..\.x$/
|
||||
before_script:
|
||||
- apk add bash build-base clang clang-analyzer argp-standalone lvm2-dev openssl-dev popt-dev util-linux-dev json-c-dev device-mapper gettext-dev libssh-dev automake autoconf libtool tar asciidoctor
|
||||
- export CC="${COMPILER}${COMPILER_VERSION:+-$COMPILER_VERSION}"
|
||||
- export CXX="${COMPILER}++${COMPILER_VERSION:+-$COMPILER_VERSION}"
|
||||
|
||||
.gitlab-shared-gcc:
|
||||
extends:
|
||||
- .gitlab-shared-docker
|
||||
- .gitlab-shared-docker-ubuntu
|
||||
variables:
|
||||
COMPILER: "gcc"
|
||||
COMPILER_VERSION: "11"
|
||||
RUN_SSH_PLUGIN_TEST: "1"
|
||||
COMPILER_VERSION: "14"
|
||||
CC: "gcc-14"
|
||||
|
||||
.gitlab-shared-clang:
|
||||
extends:
|
||||
- .gitlab-shared-docker
|
||||
- .gitlab-shared-docker-ubuntu
|
||||
variables:
|
||||
COMPILER: "clang"
|
||||
COMPILER_VERSION: "17"
|
||||
RUN_SSH_PLUGIN_TEST: "1"
|
||||
COMPILER_VERSION: "20"
|
||||
CC: "clang-20"
|
||||
|
||||
.gitlab-shared-gcc-alpine:
|
||||
extends:
|
||||
- .gitlab-shared-docker-alpine
|
||||
variables:
|
||||
COMPILER: "gcc"
|
||||
CC: "gcc"
|
||||
|
||||
.gitlab-shared-clang-alpine:
|
||||
extends:
|
||||
- .gitlab-shared-docker-alpine
|
||||
variables:
|
||||
COMPILER: "clang"
|
||||
CC: "clang"
|
||||
|
||||
@@ -1,106 +0,0 @@
|
||||
.rhel-openssl-backend:
|
||||
extends:
|
||||
- .dump_kernel_log
|
||||
before_script:
|
||||
- >
|
||||
sudo yum -y -q install
|
||||
autoconf automake device-mapper-devel gcc gettext-devel json-c-devel
|
||||
libblkid-devel libpwquality-devel libselinux-devel libssh-devel libtool
|
||||
libuuid-devel make popt-devel libsepol-devel nc openssh-clients passwd
|
||||
pkgconfig sharutils sshpass tar uuid-devel vim-common device-mapper
|
||||
expect gettext git jq keyutils openssl-devel openssl gem > /dev/null 2>&1
|
||||
- sudo gem install asciidoctor
|
||||
- sudo -E git clean -xdf
|
||||
- ./autogen.sh
|
||||
- ./configure --enable-fips --enable-pwquality --with-crypto_backend=openssl --enable-asciidoc
|
||||
|
||||
# non-FIPS jobs
|
||||
|
||||
test-main-commit-rhel8:
|
||||
extends:
|
||||
- .rhel-openssl-backend
|
||||
tags:
|
||||
- libvirt
|
||||
- rhel8
|
||||
stage: test
|
||||
interruptible: true
|
||||
variables:
|
||||
RUN_SSH_PLUGIN_TEST: "1"
|
||||
rules:
|
||||
- if: $RUN_SYSTEMD_PLUGIN_TEST != null
|
||||
when: never
|
||||
- if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
|
||||
when: never
|
||||
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /v2\..\.x$/
|
||||
script:
|
||||
- make -j
|
||||
- make -j -C tests check-programs
|
||||
- sudo -E make check
|
||||
|
||||
test-main-commit-rhel9:
|
||||
extends:
|
||||
- .rhel-openssl-backend
|
||||
tags:
|
||||
- libvirt
|
||||
- rhel9
|
||||
stage: test
|
||||
interruptible: true
|
||||
variables:
|
||||
RUN_SSH_PLUGIN_TEST: "1"
|
||||
rules:
|
||||
- if: $RUN_SYSTEMD_PLUGIN_TEST != null
|
||||
when: never
|
||||
- if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
|
||||
when: never
|
||||
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /v2\..\.x$/
|
||||
script:
|
||||
- make -j
|
||||
- make -j -C tests check-programs
|
||||
- sudo -E make check
|
||||
|
||||
# FIPS jobs
|
||||
|
||||
test-main-commit-rhel8-fips:
|
||||
extends:
|
||||
- .rhel-openssl-backend
|
||||
tags:
|
||||
- libvirt
|
||||
- rhel8-fips
|
||||
stage: test
|
||||
interruptible: true
|
||||
variables:
|
||||
RUN_SSH_PLUGIN_TEST: "1"
|
||||
rules:
|
||||
- if: $RUN_SYSTEMD_PLUGIN_TEST != null
|
||||
when: never
|
||||
- if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
|
||||
when: never
|
||||
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /v2\..\.x$/
|
||||
script:
|
||||
- fips-mode-setup --check || exit 1
|
||||
- make -j
|
||||
- make -j -C tests check-programs
|
||||
- sudo -E make check
|
||||
|
||||
test-main-commit-rhel9-fips:
|
||||
extends:
|
||||
- .rhel-openssl-backend
|
||||
tags:
|
||||
- libvirt
|
||||
- rhel9-fips
|
||||
stage: test
|
||||
interruptible: true
|
||||
allow_failure: true
|
||||
variables:
|
||||
RUN_SSH_PLUGIN_TEST: "1"
|
||||
rules:
|
||||
- if: $RUN_SYSTEMD_PLUGIN_TEST != null
|
||||
when: never
|
||||
- if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
|
||||
when: never
|
||||
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /v2\..\.x$/
|
||||
script:
|
||||
- fips-mode-setup --check || exit 1
|
||||
- make -j
|
||||
- make -j -C tests check-programs
|
||||
- sudo -E make check
|
||||
22
.gitlab/ci/run_csmock
Executable file
22
.gitlab/ci/run_csmock
Executable file
@@ -0,0 +1,22 @@
|
||||
#!/bin/bash
|
||||
|
||||
CSMOCK="sudo /usr/bin/csmock"
|
||||
CSMOCK_TOOLS="gcc,clang,cppcheck,shellcheck"
|
||||
CSMOCK_TXZ="cryptsetup-csmock-results.tar.xz"
|
||||
CSMOCK_ERR="cryptsetup-csmock-results/scan-results.err"
|
||||
|
||||
$CSMOCK cryptsetup-*.src.rpm \
|
||||
--keep-going --force \
|
||||
--cswrap-timeout 300 \
|
||||
--skip-patches \
|
||||
--tools $CSMOCK_TOOLS \
|
||||
--output $CSMOCK_TXZ \
|
||||
--gcc-analyze \
|
||||
--cppcheck-add-flag=--check-level=exhaustive \
|
||||
|| { echo "csmock command failed"; exit 2; }
|
||||
|
||||
tar xJf $CSMOCK_TXZ $CSMOCK_ERR --strip-components 1 \
|
||||
&& test -s $CSMOCK_ERR \
|
||||
&& { echo "csmock discovered important errors"; echo 3; }
|
||||
|
||||
exit 0
|
||||
31
.gitlab/ci/spellcheck
Executable file
31
.gitlab/ci/spellcheck
Executable file
@@ -0,0 +1,31 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
DIR="_spellcheck"
|
||||
|
||||
[ ! -d $DIR ] && mkdir $DIR
|
||||
|
||||
echo "[SPELLINTIAN]"
|
||||
git ls-tree -rz --name-only HEAD | grep -Evz -e '\.(pdf|xz)$' -e ^po/ | \
|
||||
xargs -r0 spellintian | \
|
||||
grep -v "(duplicate word)" | \
|
||||
grep -v "docs/" | tee $DIR/spell1.txt
|
||||
|
||||
echo "[CODESPELL]"
|
||||
git ls-tree -rz --name-only HEAD | grep -Evz -e '\.(pdf|xz)$' -e ^po/ | \
|
||||
xargs -r0 codespell | \
|
||||
grep -v "EXPCT" | \
|
||||
grep -v "params, prams" | \
|
||||
grep -v "pad, padded" | \
|
||||
grep -v "CIPHER, CHIP" | \
|
||||
grep -v "gost" | \
|
||||
grep -v "userA" | \
|
||||
grep -v "re-use" | \
|
||||
grep -v "fo ==" | \
|
||||
grep -v "docs/" | tee $DIR/spell2.txt
|
||||
|
||||
|
||||
[ -s $DIR/spell1.txt ] && exit 1
|
||||
[ -s $DIR/spell2.txt ] && exit 2
|
||||
|
||||
exit 0
|
||||
@@ -9,7 +9,10 @@
|
||||
|
||||
### Debug log
|
||||
<!-- Paste a debug log of the failing command (add --debug option) between the markers below (to keep raw debug format).-->
|
||||
<!-- We need a lot of information from the debug log; without it, we cannot process your report. -->
|
||||
<!-- Debug log does not contain any private information. Do not paste private data; we'll ask you for more information if needed. -->
|
||||
```
|
||||
Output with --debug option:
|
||||
|
||||
```
|
||||
<!-- NOTE: WITHOUT DEBUG LOG, THE BUG REPORT WILL BE CLOSED. ALSO, PLEASE DO NOT TRY TO REMOVE PARTS OF THE DEBUG LOG! -->
|
||||
|
||||
158
CONTRIBUTING.md
Normal file
158
CONTRIBUTING.md
Normal file
@@ -0,0 +1,158 @@
|
||||
Contributing to cryptsetup
|
||||
==========================
|
||||
For basic information about the cryptsetup project, please read [README](README.md).
|
||||
|
||||
The Cryptsetup project uses free, open-source licenses; details are described in [licensing](README.licensing).
|
||||
|
||||
For contribution code or documentation to the cryptsetup project, you must have the necessary rights to the content, and your contribution must be provided under the required license.
|
||||
|
||||
We welcome contributions from everyone.
|
||||
|
||||
Cryptsetup is an independent project with much volunteer effort, and our resources are limited.
|
||||
Following the guidelines specified in this file makes it easier for us to process your issue.
|
||||
|
||||
Project maintainers can remove or reject abusive or otherwise unacceptable comments or code.
|
||||
|
||||
Git repository
|
||||
--------------
|
||||
The primary repository is located at [gitlab.com/cryptsetup/cryptsetup](https://gitlab.com/cryptsetup/cryptsetup).
|
||||
The development branch is ``main``; minor stable releases can use their branches with cherry-picked or backported patches.
|
||||
|
||||
There are backup mirrors located at [github.com/mbroz/cryptsetup](https://github.com/mbroz/cryptsetup) and [git.kernel.org/pub/scm/utils/cryptsetup/cryptsetup.git](https://git.kernel.org/pub/scm/utils/cryptsetup/cryptsetup.git).
|
||||
|
||||
How to make a bug report
|
||||
------------------------
|
||||
To report an issue or feature request, please use GitLab [cryptsetup issue tracker](https://gitlab.com/cryptsetup/cryptsetup/-/issues).
|
||||
|
||||
Before reporting an issue, please try to search documentation and existing issues. Always try to reproduce the problem on the latest supported release.
|
||||
Please *always* collect and attach ``--debug`` log and other information as instructed in the issue template.
|
||||
Even if you think the problem is obvious, we need logged information about the environment (like versions of kernel modules, etc.).
|
||||
|
||||
Please do not report distribution-specific issues if they are not present in the latest upstream release.
|
||||
For such reports, please use downstream distribution-specific trackers.
|
||||
If the issue is related to upstream, downstream maintainers will redirect you here, or upstream maintainers will join the discussion.
|
||||
|
||||
If you think that you found some security bug, please follow the instructions in the [SECURITY](SECURITY.md) file.
|
||||
|
||||
How to contribute changes to cryptsetup
|
||||
---------------------------------------
|
||||
The following notes are a very short introduction to cryptsetup internal processes and an overview of generic rules that should be followed for all changes.
|
||||
|
||||
Changes from developers and external contributors should go through the GitLab repository [merge reguests](https://gitlab.com/cryptsetup/cryptsetup/-/merge_requests).
|
||||
Alternatively (for trivial changes), you can send a patch to [cryptsetup mailing list](mailto:cryptsetup@lists.linux.dev).
|
||||
|
||||
Please do not write personal emails with questions or patches to maintainers and developers.
|
||||
|
||||
### Project structure
|
||||
Cryptsetup projects include a libcryptsetup library, tools, token plugins, documentation, and a test suite.
|
||||
|
||||
Cryptsetup library (libcryptsetup) exports [versioned symbols](lib/libcryptsetup.sym).
|
||||
Tools (cryptsetup, veritysetup, integritysetup) use libcryptsetup shared library.
|
||||
Some isolated parts in the lib directory can be reused for tools (the source is recompiled).
|
||||
|
||||
The basic directory structure in the repository is
|
||||
```
|
||||
├── docs - Documentation and release notes.
|
||||
├── lib - libcryptsetup implementation
|
||||
│ ├── bitlk - Bitlocker format
|
||||
│ ├── crypto_backend - Cryptography backend
|
||||
│ ├── fvault2 - FileVault2 format
|
||||
│ ├── integrity - Linux dm-integrity interface
|
||||
│ ├── loopaes - Linux LoopAES format
|
||||
│ ├── luks1 - LUKS1 format
|
||||
│ ├── luks2 - LUKS2 format including OPAL2 SED
|
||||
│ ├── tcrypt - TrueCrypt / VeraCrypt format
|
||||
│ └── verity - Linux dm-verity interface
|
||||
├── man - Manual pages (in AsciiDoc format)
|
||||
├── misc - Miscellaneous additions
|
||||
├── po - Translation files
|
||||
├── scripts - Scripts for system configuration
|
||||
├── src - Tools implementation
|
||||
├── tests - Testsuite (test units, regression tests, fuzzing)
|
||||
└── tokens - Token plugins
|
||||
```
|
||||
### Coordination with other projects
|
||||
The cryptsetup tools and library use low-level functions that depend on many other subsystems.
|
||||
Currently, the project is supported only for Linux (it will not work on Android or other systems).
|
||||
|
||||
Cryptsetup project requires some parts of the Linux kernel, notably the *Device Mapper* (dm-crypt, dm-integrity, dm-verity, dm-zero modules) and kernel *userspace cryptographic interface*.
|
||||
Missing kernel interface can significantly limit (or even disallow) cryptsetup functionality.
|
||||
|
||||
Integration in operating systems also depends on several other projects, most notably *systemd* (that implements its own tooling using libcryptsetup) and *util-Linux* (*blkid* parsing of supported format metadata). Some changes must be synchronized in all needed places (kernel, blkid, libcryptsetup).
|
||||
|
||||
Several other projects implement their own token metadata (either through binary token plugins or through generic libcryptsetup JSON token access functions).
|
||||
|
||||
### Used cryptography algorithms
|
||||
Cryptsetup avoids implementing cryptographic primitives but uses cryptographic libraries.
|
||||
Exceptions were PBKDF internal implementations - PBKDF2 and Argon2 until these were integrated into major cryptographic libraries.
|
||||
|
||||
Cryptsetup can be compiled with several cryptographic libraries backend (OpenSSL, libgcrypt, Nettle, NSS, and Linux kernel userspace API).
|
||||
OpenSSL is the default and strongly recommended configuration.
|
||||
|
||||
If the cryptographic library does not implement some cryptographic primitive (for example, if running in a FIPS-140 environment or just
|
||||
because it does not include it at all), functionality could be limited.
|
||||
|
||||
### Configuration and versioning
|
||||
Cryptsetup can be configured using *Autoconf* or *Meson*. Autoconf support is being deprecated in the long term.
|
||||
Currently, all new configuration options must be implemented in both systems.
|
||||
|
||||
Cryptsetup intentionally does not use a system configuration file (located in /etc).
|
||||
All functionality must be determined dynamically.
|
||||
|
||||
All related /etc configuration files (crypttab, fstab and others) are maintained by systemd (in some legacy distributions by cryptsetup downstream).
|
||||
|
||||
Cryptsetup uses [semantic versioning](https://semver.org/).
|
||||
Major and minor releases are always based on the main git branch; the minor stable (patch) versions can have some specific branch with backported or cherry-picked patches (from the main branch).
|
||||
Usually, minor releases happen twice per year and stable patch updates according to reported bugs (in 1-3 month intervals).
|
||||
|
||||
### Compilation and debugging
|
||||
The library and tools are written in C language; we require C99 and support gcc and Clang compilers.
|
||||
Manual pages are generated from AsciiDoc sources and libcryptsetup API documentation by Doxygen (from libcryptsetup.h comments).
|
||||
Testsuite is a combination of local C utilities, fuzzing implementation in C++, bash scripts, and uses many other system utilities.
|
||||
|
||||
All tools contain compiled-in debug messages that are available through --debug options.
|
||||
|
||||
With Autoconf and libtool, you can run the cryptsetup tool in the debugger without installation using this one-line script:
|
||||
```
|
||||
libtool --mode=execute gdb --args ./cryptsetup --debug $@
|
||||
```
|
||||
This will ensure that a properly compiled libcryptsetup file is used.
|
||||
|
||||
### Coding style
|
||||
Cryptsetup uses [Linux kernel coding style](https://cdn.kernel.org/doc/html/latest/process/coding-style.html) for libcryptsetup and tools (where applicable) with some additional notes:
|
||||
- Use tabulators for indentation; the line should not exceed 100 characters with an 8-character tabulator. Otherwise, use a tab of any length. :-).
|
||||
- The minimal C standard required is C99.
|
||||
- The ``goto`` use is allowed only for error path (``goto out`` for common code path, ``goto err`` for specific error code path).
|
||||
- Split patches per change; do not submit huge patches combining several changes.
|
||||
- Use an elaborative description in the patch header.
|
||||
- No need to use sign-off-by lines.
|
||||
- Use name prefixes (``crypt_``, ``LUKS2_`` and similar).
|
||||
- Avoid extensive preprocessor use (specifically conditional ``#if`` or ``#ifdef`` sections).
|
||||
- To check detected configuration options stored in config.h, always use ``#if SOMETHING`` (do NOT use ``#ifdef``).
|
||||
- Use output only through ``log_err, log_std, log_verbose, log_dbg`` macros.
|
||||
The ``log_dbg`` is always in English; the others should be wrapped in the ``_()`` macro for translation.
|
||||
- Use ``assert()`` but only for simple invariants and variables (avoid calling functions).
|
||||
Do not use assert for user-defined input (this should be a normal error path).
|
||||
- The code style is quite relaxed in testing scripts (code there is not intended for production use).
|
||||
|
||||
### General rules and testing
|
||||
- Cryptsetup should work on all architectures supported by the Linux kernel.
|
||||
Only very few functionalities require specific hardware (notably Opal SED support).
|
||||
If you want to introduce some specific hardware support, please discuss it with the maintainers first.
|
||||
|
||||
- All code changes should go through merge requests and reviews.
|
||||
Code can be merged after review approval (done by someone with the commit right to the development repository), but reviews from external people are very welcome, too.
|
||||
|
||||
- All new functionality must come with at least rudimentary coverage in the test suite.
|
||||
Always run the test suite before opening the merge request (``make check`` with root privilege).
|
||||
|
||||
- We have continuous integration (CI) that runs many tests automatically, but the output is not directly visible for external merge request authors (for security reasons).
|
||||
All CI scripts are available in .gitlab and .github folders in the project repository.
|
||||
|
||||
Maintainers will provide you log files if anything fails. Your code must produce no warnings before it is merged.
|
||||
|
||||
- We run compilation with many extended [gcc](.gitlab/ci/gcc-Wall) and [Clang](.gitlab/ci/clang-Wall) warnings and include some analyzers, notably
|
||||
- [Coverity](https://scan.coverity.com), GitHub CodeQL, Clang scan-build, and gcc static analyzer, and
|
||||
- fuzzing integrated in [OSS-fuzz project](https://github.com/google/oss-fuzz/tree/master/projects/cryptsetup).
|
||||
|
||||
- Testsuite can also partially run under Valgrind dynamic analyzer with ``make valgrind-check``.
|
||||
34
FAQ.md
34
FAQ.md
@@ -38,7 +38,7 @@
|
||||
LUKS1 and LUKS2.
|
||||
|
||||
The LUKS1 on-disk format specification is at
|
||||
https://www.kernel.org/pub/linux/utils/cryptsetup/LUKS_docs/on-disk-format.pdf
|
||||
https://cdn.kernel.org/pub/linux/utils/cryptsetup/LUKS_docs/on-disk-format.pdf
|
||||
The LUKS2 on-disk format specification is at
|
||||
https://gitlab.com/cryptsetup/LUKS2-docs
|
||||
|
||||
@@ -169,17 +169,12 @@
|
||||
me write the section. Please note that by contributing to this FAQ,
|
||||
you accept the license described below.
|
||||
|
||||
This work is under the "Attribution-Share Alike 3.0 Unported" license,
|
||||
which means distribution is unlimited, you may create derived works, but
|
||||
This work is licensed under a Creative Commons CC-BY-SA-4.0
|
||||
"Attribution-ShareAlike 4.0 International" license which means
|
||||
distribution is unlimited, you may create derived works, but
|
||||
attributions to original authors and this license statement must be
|
||||
retained and the derived work must be under the same license. See
|
||||
https://creativecommons.org/licenses/by-sa/3.0/ for more details of the
|
||||
license.
|
||||
|
||||
Side note: I did text license research some time ago and I think this
|
||||
license is best suited for the purpose at hand and creates the least
|
||||
problems.
|
||||
|
||||
retained and the derived work must be under the same license.
|
||||
See https://creativecommons.org/licenses/by-sa/4.0/ for more details.
|
||||
|
||||
* **1.6 Where is the project website?**
|
||||
|
||||
@@ -710,9 +705,12 @@
|
||||
this. The only legitimate reason I can think of is if you want to have
|
||||
two LUKS devices with the same volume key. Even then, I think it would
|
||||
be preferable to just use key-slots with the same passphrase, or to use
|
||||
plain dm-crypt instead. If you really have a good reason, please tell
|
||||
me. If I am convinced, I will add how to do this here.
|
||||
plain dm-crypt instead.
|
||||
|
||||
Use the --volume-key-file option, like this:
|
||||
```
|
||||
cryptsetup luksFormat --volume-key-file keyfile /dev/loop0
|
||||
```
|
||||
|
||||
* **2.12 What are the security requirements for a key read from file?**
|
||||
|
||||
@@ -1928,10 +1926,6 @@
|
||||
Hence, LUKS has no kill option because it would do much more harm than
|
||||
good.
|
||||
|
||||
Still, if you have a good use-case (i.e. non-abstract real-world
|
||||
situation) where a Nuke-Option would actually be beneficial, please let
|
||||
me know.
|
||||
|
||||
|
||||
* **5.22 Does cryptsetup open network connections to websites, etc. ?**
|
||||
|
||||
@@ -2685,8 +2679,7 @@ can be converted to the raw volume key for example via:
|
||||
|
||||
Note that at the time this FAQ item was written, 1.5.4 was the latest
|
||||
1.5.x version and it has the flaw, i.e. works with the old Whirlpool
|
||||
version. Possibly later 1.5.x versions will work as well. If not,
|
||||
please let me know.
|
||||
version. Possibly later 1.5.x versions will work as well.
|
||||
|
||||
The only two ways to access older LUKS containers created with Whirlpool
|
||||
are to either decrypt with an old gcrypt version that has the flaw or to
|
||||
@@ -2802,8 +2795,7 @@ can be converted to the raw volume key for example via:
|
||||
03) Creating your own initrd
|
||||
|
||||
The two examples below should give you most of what is needed. This is
|
||||
tested with LUKS1 and should work with LUKS2 as well. If not, please
|
||||
let me know.
|
||||
tested with LUKS1 and should work with LUKS2 as well.
|
||||
|
||||
Here is a really minimal example. It does nothing but set up some
|
||||
things and then drop to an interactive shell. It is perfect to try out
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
EXTRA_DIST = README.md SECURITY.md COPYING.LGPL FAQ.md docs misc autogen.sh
|
||||
EXTRA_DIST = README.md SECURITY.md README.licensing CONTRIBUTING.md FAQ.md docs misc autogen.sh
|
||||
EXTRA_DIST += meson_options.txt \
|
||||
meson.build \
|
||||
lib/crypto_backend/argon2/meson.build \
|
||||
@@ -9,6 +9,7 @@ EXTRA_DIST += meson_options.txt \
|
||||
scripts/meson.build \
|
||||
src/meson.build \
|
||||
tests/meson.build \
|
||||
tests/fuzz/meson.build \
|
||||
tokens/meson.build \
|
||||
tokens/ssh/meson.build
|
||||
|
||||
@@ -24,8 +25,7 @@ AM_CPPFLAGS = \
|
||||
-DLIBDIR=\""$(libdir)"\" \
|
||||
-DPREFIX=\""$(prefix)"\" \
|
||||
-DSYSCONFDIR=\""$(sysconfdir)"\" \
|
||||
-DVERSION=\""$(VERSION)"\" \
|
||||
-DEXTERNAL_LUKS2_TOKENS_PATH=\"${EXTERNAL_LUKS2_TOKENS_PATH}\"
|
||||
-DVERSION=\""$(VERSION)"\"
|
||||
AM_CFLAGS = -Wall
|
||||
AM_CXXFLAGS = -Wall
|
||||
AM_LDFLAGS =
|
||||
|
||||
20
README.licensing
Normal file
20
README.licensing
Normal file
@@ -0,0 +1,20 @@
|
||||
The cryptsetup project does not use the same license for all of the code and documentation.
|
||||
|
||||
There is code and documentation under:
|
||||
|
||||
* GPL-2.0-or-later - GNU General Public License version 2, or any later version
|
||||
|
||||
* LGPL-2.1-or-later WITH cryptsetup-OpenSSL-exception
|
||||
* LGPL-2.1-or-later - GNU Lesser General Public License 2.1 or any later version,
|
||||
(with cryptsetup-OpenSSL-exception where applicable)
|
||||
|
||||
* Apache-2.0 - Apache License 2.0
|
||||
|
||||
* CC-BY-SA-4.0 - Creative Commons Attribution Share Alike 4.0 International
|
||||
|
||||
* Public Domain
|
||||
|
||||
Please, check the source code for more details.
|
||||
|
||||
The ./COPYING file (GPL-2.0-or-later) is the default license for code without
|
||||
an explicitly defined license.
|
||||
34
README.md
34
README.md
@@ -30,34 +30,22 @@ which enables users to transport or migrate data seamlessly.
|
||||
* The latest version of the
|
||||
[LUKS2 format specification](https://gitlab.com/cryptsetup/LUKS2-docs).
|
||||
* The latest version of the
|
||||
[LUKS1 format specification](https://www.kernel.org/pub/linux/utils/cryptsetup/LUKS_docs/on-disk-format.pdf).
|
||||
[LUKS1 format specification](https://cdn.kernel.org/pub/linux/utils/cryptsetup/LUKS_docs/on-disk-format.pdf).
|
||||
* [Project home page](https://gitlab.com/cryptsetup/cryptsetup/).
|
||||
* [Frequently asked questions (FAQ)](https://gitlab.com/cryptsetup/cryptsetup/wikis/FrequentlyAskedQuestions)
|
||||
|
||||
Download
|
||||
--------
|
||||
Release notes and tarballs are available at
|
||||
[kernel.org](https://www.kernel.org/pub/linux/utils/cryptsetup/).
|
||||
[kernel.org](https://cdn.kernel.org/pub/linux/utils/cryptsetup/).
|
||||
|
||||
**The latest stable cryptsetup release candidate version is 2.7.0-rc0**
|
||||
* [cryptsetup-2.7.0-rc0.tar.xz](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.7/cryptsetup-2.7.0-rc0.tar.xz)
|
||||
* Signature [cryptsetup-2.7.0-rc0.tar.sign](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.7/cryptsetup-2.7.0-rc0.tar.sign)
|
||||
**The latest stable cryptsetup release version is 2.8.1**
|
||||
* [cryptsetup-2.8.1.tar.xz](https://cdn.kernel.org/pub/linux/utils/cryptsetup/v2.8/cryptsetup-2.8.1.tar.xz)
|
||||
* Signature [cryptsetup-2.8.1.tar.sign](https://cdn.kernel.org/pub/linux/utils/cryptsetup/v2.8/cryptsetup-2.8.1.tar.sign)
|
||||
_(You need to decompress file first to check signature.)_
|
||||
* [Cryptsetup 2.7.0-rc0 Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.7/v2.7.0-rc0-ReleaseNotes).
|
||||
* [Cryptsetup 2.8.1 Release Notes](https://cdn.kernel.org/pub/linux/utils/cryptsetup/v2.8/v2.8.1-ReleaseNotes).
|
||||
|
||||
**The latest stable cryptsetup release version is 2.6.1**
|
||||
* [cryptsetup-2.6.1.tar.xz](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.6/cryptsetup-2.6.1.tar.xz)
|
||||
* Signature [cryptsetup-2.6.1.tar.sign](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.6/cryptsetup-2.6.1.tar.sign)
|
||||
_(You need to decompress file first to check signature.)_
|
||||
* [Cryptsetup 2.6.1 Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.6/v2.6.1-ReleaseNotes).
|
||||
|
||||
Previous versions
|
||||
* [Version 2.5.0](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.5/cryptsetup-2.5.0.tar.xz) -
|
||||
[Signature](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.5/cryptsetup-2.5.0.tar.sign) -
|
||||
[Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.5/v2.5.0-ReleaseNotes).
|
||||
* [Version 1.7.5](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.7/cryptsetup-1.7.5.tar.xz) -
|
||||
[Signature](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.7/cryptsetup-1.7.5.tar.sign) -
|
||||
[Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.7/v1.7.5-ReleaseNotes).
|
||||
[Previous versions](https://cdn.kernel.org/pub/linux/utils/cryptsetup)
|
||||
|
||||
Source and API documentation
|
||||
----------------------------
|
||||
@@ -82,8 +70,7 @@ Below are the packages needed to build for certain Linux distributions:
|
||||
|
||||
**For Fedora**:
|
||||
```
|
||||
git gcc make autoconf automake gettext-devel pkgconfig openssl-devel popt-devel device-mapper-devel
|
||||
libuuid-devel json-c-devel libblkid-devel findutils libtool libssh-devel tar
|
||||
git gcc make autoconf automake gettext-devel pkgconfig openssl-devel popt-devel device-mapper-devel libuuid-devel json-c-devel libblkid-devel findutils libtool libssh-devel tar rubygem-asciidoctor
|
||||
|
||||
Optionally: libargon2-devel libpwquality-devel
|
||||
```
|
||||
@@ -94,14 +81,13 @@ sharutils device-mapper jq vim-common expect keyutils netcat shadow-utils openss
|
||||
|
||||
**For Debian and Ubuntu**:
|
||||
```
|
||||
git gcc make autoconf automake autopoint pkg-config libtool gettext libssl-dev libdevmapper-dev
|
||||
libpopt-dev uuid-dev libsepol1-dev libjson-c-dev libssh-dev libblkid-dev tar
|
||||
git gcc make autoconf automake autopoint pkg-config libtool gettext libssl-dev libdevmapper-dev libpopt-dev uuid-dev libsepol-dev libjson-c-dev libssh-dev libblkid-dev tar asciidoctor
|
||||
|
||||
Optionally: libargon2-0-dev libpwquality-dev
|
||||
```
|
||||
To run the internal testsuite (make check) you also need to install
|
||||
```
|
||||
sharutils dmsetup jq xxd expect keyutils netcat passwd openssh-client sshpass
|
||||
sharutils dmsetup jq xxd expect keyutils netcat-openbsd passwd openssh-client sshpass
|
||||
```
|
||||
|
||||
Note that the list may change as Linux distributions evolve.
|
||||
|
||||
85
configure.ac
85
configure.ac
@@ -1,9 +1,9 @@
|
||||
AC_PREREQ([2.67])
|
||||
AC_INIT([cryptsetup],[2.7.0-rc0])
|
||||
AC_INIT([cryptsetup],[2.9.0-git])
|
||||
|
||||
dnl library version from <major>.<minor>.<release>[-<suffix>]
|
||||
LIBCRYPTSETUP_VERSION=$(echo $PACKAGE_VERSION | cut -f1 -d-)
|
||||
LIBCRYPTSETUP_VERSION_INFO=22:0:10
|
||||
LIBCRYPTSETUP_VERSION_INFO=23:0:11
|
||||
|
||||
AM_SILENT_RULES([yes])
|
||||
AC_CONFIG_SRCDIR(src/cryptsetup.c)
|
||||
@@ -132,7 +132,6 @@ AC_C_BIGENDIAN
|
||||
AC_TYPE_OFF_T
|
||||
AC_SYS_LARGEFILE
|
||||
AC_FUNC_FSEEKO
|
||||
AC_PROG_GCC_TRADITIONAL
|
||||
AC_FUNC_STRERROR_R
|
||||
|
||||
dnl ==========================================================================
|
||||
@@ -346,7 +345,7 @@ AC_DEFUN([CONFIGURE_OPENSSL], [
|
||||
|
||||
saved_LIBS=$LIBS
|
||||
AC_CHECK_DECLS([OSSL_get_max_threads], [], [], [#include <openssl/thread.h>])
|
||||
AC_CHECK_DECLS([OSSL_KDF_PARAM_ARGON2_VERSION], [], [], [#include <openssl/core_names.h>])
|
||||
AC_CHECK_DECLS([OSSL_KDF_PARAM_ARGON2_VERSION], [use_internal_argon2=0], [], [#include <openssl/core_names.h>])
|
||||
LIBS=$saved_LIBS
|
||||
])
|
||||
|
||||
@@ -400,6 +399,23 @@ AC_DEFUN([CONFIGURE_NETTLE], [
|
||||
NO_FIPS([])
|
||||
])
|
||||
|
||||
AC_DEFUN([CONFIGURE_MBEDTLS], [
|
||||
AC_CHECK_HEADERS(mbedtls/version.h,,
|
||||
[AC_MSG_ERROR([You need mbedTLS cryptographic library.])])
|
||||
|
||||
saved_LIBS=$LIBS
|
||||
AC_CHECK_LIB(mbedcrypto, mbedtls_md_init,,
|
||||
[AC_MSG_ERROR([You need mbedTLS cryptographic library.])])
|
||||
AC_CHECK_FUNCS(mbedtls_pkcs5_pbkdf2_hmac_ext)
|
||||
CRYPTO_LIBS=$LIBS
|
||||
LIBS=$saved_LIBS
|
||||
|
||||
CRYPTO_STATIC_LIBS=$CRYPTO_LIBS
|
||||
use_internal_pbkdf2=0
|
||||
use_internal_argon2=1
|
||||
NO_FIPS([])
|
||||
])
|
||||
|
||||
dnl ==========================================================================
|
||||
saved_LIBS=$LIBS
|
||||
|
||||
@@ -482,7 +498,7 @@ fi
|
||||
|
||||
dnl Crypto backend configuration.
|
||||
AC_ARG_WITH([crypto_backend],
|
||||
AS_HELP_STRING([--with-crypto_backend=BACKEND], [crypto backend (gcrypt/openssl/nss/kernel/nettle) [openssl]]),
|
||||
AS_HELP_STRING([--with-crypto_backend=BACKEND], [crypto backend (gcrypt/openssl/nss/kernel/nettle/mbedtls) [openssl]]),
|
||||
[], [with_crypto_backend=openssl])
|
||||
|
||||
dnl Kernel crypto API backend needed for benchmark and tcrypt
|
||||
@@ -502,6 +518,7 @@ case $with_crypto_backend in
|
||||
nss) CONFIGURE_NSS([]) ;;
|
||||
kernel) CONFIGURE_KERNEL([]) ;;
|
||||
nettle) CONFIGURE_NETTLE([]) ;;
|
||||
mbedtls) CONFIGURE_MBEDTLS([]) ;;
|
||||
*) AC_MSG_ERROR([Unknown crypto backend.]) ;;
|
||||
esac
|
||||
AM_CONDITIONAL(CRYPTO_BACKEND_GCRYPT, test "$with_crypto_backend" = "gcrypt")
|
||||
@@ -509,6 +526,7 @@ AM_CONDITIONAL(CRYPTO_BACKEND_OPENSSL, test "$with_crypto_backend" = "openssl")
|
||||
AM_CONDITIONAL(CRYPTO_BACKEND_NSS, test "$with_crypto_backend" = "nss")
|
||||
AM_CONDITIONAL(CRYPTO_BACKEND_KERNEL, test "$with_crypto_backend" = "kernel")
|
||||
AM_CONDITIONAL(CRYPTO_BACKEND_NETTLE, test "$with_crypto_backend" = "nettle")
|
||||
AM_CONDITIONAL(CRYPTO_BACKEND_MBEDTLS, test "$with_crypto_backend" = "mbedtls")
|
||||
|
||||
AM_CONDITIONAL(CRYPTO_INTERNAL_PBKDF2, test $use_internal_pbkdf2 = 1)
|
||||
AC_DEFINE_UNQUOTED(USE_INTERNAL_PBKDF2, [$use_internal_pbkdf2], [Use internal PBKDF2])
|
||||
@@ -521,9 +539,9 @@ AC_ARG_ENABLE([internal-argon2],
|
||||
AC_ARG_ENABLE([libargon2],
|
||||
AS_HELP_STRING([--enable-libargon2], [enable external libargon2 (PHC) library (disables internal bundled version)]))
|
||||
|
||||
if test $use_internal_argon2 = 0 -o "x$enable_internal_argon2" = "xno" ; then
|
||||
if test "x$enable_internal_argon2" = "xyes" -o "x$enable_libargon" = "xyes"; then
|
||||
AC_MSG_WARN([Argon2 in $with_crypto_backend lib is used; internal Argon2 options are ignored.])
|
||||
if test $use_internal_argon2 = 0 || ( test "x$enable_internal_argon2" = "xno" && test "x$enable_libargon2" != "xyes" ); then
|
||||
if test "x$enable_internal_argon2" = "xyes" || test "x$enable_libargon2" = "xyes"; then
|
||||
AC_MSG_NOTICE([Argon2 in $with_crypto_backend lib is used; internal Argon2 options are ignored.])
|
||||
fi
|
||||
enable_internal_argon2=no
|
||||
enable_internal_sse_argon2=no
|
||||
@@ -535,6 +553,7 @@ elif test "x$enable_libargon2" = "xyes" ; then
|
||||
AC_CHECK_DECL(Argon2_id,,[AC_MSG_ERROR([You need more recent Argon2 library with support for Argon2id.])], [#include <argon2.h>])
|
||||
PKG_CHECK_MODULES([LIBARGON2], [libargon2],,[LIBARGON2_LIBS="-largon2"])
|
||||
enable_internal_argon2=no
|
||||
use_internal_argon2=0
|
||||
else
|
||||
AC_MSG_WARN([Argon2 bundled (slow) reference implementation will be used, please consider to use system library with --enable-libargon2.])
|
||||
|
||||
@@ -661,8 +680,36 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
|
||||
])
|
||||
CFLAGS=$saved_CFLAGS
|
||||
|
||||
dnl Force compiler to use zero_call_used_regs("used") to check for the function attribute support.
|
||||
dnl Otherwise the compiler may falsely advertise it with __has_attribute operator, even though
|
||||
dnl it does not implement it on some archs.
|
||||
AC_MSG_CHECKING([for zero_call_used_regs(user)])
|
||||
saved_CFLAGS=$CFLAGS
|
||||
CFLAGS="-O0 -Werror"
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
|
||||
void _test_function(void);
|
||||
__attribute__((zero_call_used_regs("used"))) void _test_function(void) {
|
||||
volatile int *i; volatile int j = 0; if (j) *i = 0;
|
||||
}
|
||||
]],
|
||||
[[ _test_function() ]]
|
||||
)],[
|
||||
AC_DEFINE([HAVE_ATTRIBUTE_ZEROCALLUSEDREGS], 1, [Define to 1 to use __attribute__((zero_call_used_regs("used")))])
|
||||
AC_MSG_RESULT([yes])
|
||||
], [
|
||||
AC_MSG_RESULT([no])
|
||||
])
|
||||
CFLAGS=$saved_CFLAGS
|
||||
|
||||
AC_MSG_CHECKING([for systemd tmpfiles config directory])
|
||||
PKG_CHECK_VAR([systemd_tmpfilesdir], [systemd], [tmpfilesdir], [], [systemd_tmpfilesdir=no])
|
||||
if test "x$prefix" != "xNONE"; then
|
||||
saved_PKG_CONFIG=$PKG_CONFIG
|
||||
PKG_CONFIG="$PKG_CONFIG --define-variable=prefix='${prefix}'"
|
||||
PKG_CHECK_VAR([systemd_tmpfilesdir], [systemd], [tmpfilesdir], [], [systemd_tmpfilesdir=no])
|
||||
PKG_CONFIG=$saved_PKG_CONFIG
|
||||
else
|
||||
PKG_CHECK_VAR([systemd_tmpfilesdir], [systemd], [tmpfilesdir], [], [systemd_tmpfilesdir=no])
|
||||
fi
|
||||
AC_MSG_RESULT([$systemd_tmpfilesdir])
|
||||
|
||||
AC_SUBST([DEVMAPPER_LIBS])
|
||||
@@ -776,8 +823,9 @@ CS_NUM_WITH([verity-hash-block], [hash block size for verity mode], [4096])
|
||||
CS_NUM_WITH([verity-salt-size], [salt size for verity mode], [32])
|
||||
CS_NUM_WITH([verity-fec-roots], [parity bytes for verity FEC], [2])
|
||||
|
||||
CS_STR_WITH([tmpfilesdir], [override default path to directory with systemd temporary files], [])
|
||||
test -z "$with_tmpfilesdir" && with_tmpfilesdir=$systemd_tmpfilesdir
|
||||
AC_ARG_WITH([tmpfilesdir],
|
||||
AS_HELP_STRING([--with-tmpfilesdir=DIR], [override default path to directory with systemd temporary files]),
|
||||
[], [with_tmpfilesdir=$systemd_tmpfilesdir])
|
||||
test "x$with_tmpfilesdir" = "xno" || {
|
||||
CS_ABSPATH([${with_tmpfilesdir}],[with-tmpfilesdir])
|
||||
DEFAULT_TMPFILESDIR=$with_tmpfilesdir
|
||||
@@ -796,7 +844,9 @@ test -z "$with_luks2_lock_dir_perms" && with_luks2_lock_dir_perms=0700
|
||||
DEFAULT_LUKS2_LOCK_DIR_PERMS=$with_luks2_lock_dir_perms
|
||||
AC_SUBST(DEFAULT_LUKS2_LOCK_DIR_PERMS)
|
||||
|
||||
CS_STR_WITH([luks2-external-tokens-path], [path to directory with LUKSv2 external token handlers (plugins)], [LIBDIR/cryptsetup])
|
||||
AC_ARG_WITH([luks2-external-tokens-path],
|
||||
AS_HELP_STRING([--with-luks2-external-tokens-path=DIR], [path to directory with LUKSv2 external token handlers (plugins)]),
|
||||
[], [with_luks2_external_tokens_path=""])
|
||||
if test -n "$with_luks2_external_tokens_path"; then
|
||||
CS_ABSPATH([${with_luks2_external_tokens_path}],[with-luks2-external-tokens-path])
|
||||
EXTERNAL_LUKS2_TOKENS_PATH=$with_luks2_external_tokens_path
|
||||
@@ -804,6 +854,17 @@ else
|
||||
EXTERNAL_LUKS2_TOKENS_PATH="\${libdir}/cryptsetup"
|
||||
fi
|
||||
AC_SUBST(EXTERNAL_LUKS2_TOKENS_PATH)
|
||||
dnl We need to define expanded EXTERNAL_LUKS2_TOKENS_PATH, but some other code can depend on prefix=NONE.
|
||||
dnl Pretend you do not see this hack :-)
|
||||
saved_prefix=$prefix
|
||||
saved_exec_prefix=$exec_prefix
|
||||
test "x$prefix" = "xNONE" && prefix="$ac_default_prefix"
|
||||
test "x$exec_prefix" = "xNONE" && exec_prefix="$prefix"
|
||||
expanded_EXTERNAL_LUKS2_TOKENS_PATH=$(eval echo "$EXTERNAL_LUKS2_TOKENS_PATH")
|
||||
expanded_EXTERNAL_LUKS2_TOKENS_PATH=$(eval echo "$expanded_EXTERNAL_LUKS2_TOKENS_PATH")
|
||||
AC_DEFINE_UNQUOTED([EXTERNAL_LUKS2_TOKENS_PATH], ["$expanded_EXTERNAL_LUKS2_TOKENS_PATH"], [path to directory with LUKSv2 external token handlers (plugins)])
|
||||
prefix=$saved_prefix
|
||||
exec_prefix=$saved_exec_prefix
|
||||
|
||||
dnl Override default LUKS format version (for cryptsetup or cryptsetup-reencrypt format actions only).
|
||||
AC_ARG_WITH([default_luks_format],
|
||||
|
||||
@@ -12,30 +12,53 @@ no longer stored directly in dm-crypt target. Starting with cryptsetup 2.0 we
|
||||
load VK in kernel keyring by default for LUKSv2 devices (when dm-crypt with the
|
||||
feature is available).
|
||||
|
||||
Currently cryptsetup loads VK in 'logon' type kernel key so that VK is passed in
|
||||
the kernel and can't be read from userspace afterward. Also cryptsetup loads VK in
|
||||
thread keyring (before passing the reference to dm-crypt target) so that the key
|
||||
Currently, cryptsetup loads VK in 'logon' type kernel key so that VK is passed in
|
||||
the kernel and can't be read from userspace afterwards. Also, cryptsetup loads VK in
|
||||
the thread keyring (before passing the reference to dm-crypt target) so that the key
|
||||
lifetime is directly bound to the process that performs the dm-crypt setup. When
|
||||
cryptsetup process exits (for whatever reason) the key gets unlinked in kernel
|
||||
cryptsetup process exits (for whatever reason) the key gets unlinked in the kernel
|
||||
automatically. In summary, the key description visible in dm-crypt table line is
|
||||
a reference to VK that usually no longer exists in kernel keyring service if you
|
||||
used cryptsetup to for device activation.
|
||||
used cryptsetup for device activation.
|
||||
|
||||
Using this feature dm-crypt no longer maintains a direct key copy (but there's
|
||||
always at least one copy in kernel crypto layer).
|
||||
always at least one copy in the kernel crypto layer).
|
||||
|
||||
Additionally, libcryptsetup supports the linking of volume keys to
|
||||
user-specified kernel keyring with crypt_set_keyring_to_link(). The user may
|
||||
specify keyring name, key type ('user' or 'logon') and key description where
|
||||
libcryptsetup should link the verified volume key upon subsequent device
|
||||
activation (or key verification alone).
|
||||
|
||||
The volume key(s) (provided the key type is 'user') linked in the user keyring
|
||||
can be later used to activate the device via crypt_activate_by_keyslot_context()
|
||||
with CRYPT_KC_TYPE_VK_KEYRING type keyslot context
|
||||
(acquired by crypt_keyslot_context_init_by_vk_in_keyring()).
|
||||
|
||||
Example of how to use volume key linked in custom user keyring from cryptsetup
|
||||
utility:
|
||||
|
||||
1) Open the device and store the volume key to the session keyring:
|
||||
# cryptsetup open <device> --link-vk-to-keyring "@s::%user:testkey" tst
|
||||
|
||||
2) Add a keyslot using the stored volume key in a keyring:
|
||||
# cryptsetup luksAddKey <device> --volume-key-keyring "%user:testkey"
|
||||
|
||||
3) Activate the device using the volume key cached in a keyring ('user' type key)
|
||||
# cryptsetup open <device> <active_name> --volume-key-keyring "testkey"
|
||||
|
||||
II) Keyslot passphrase
|
||||
The second use case for kernel keyring is to allow cryptsetup reading the keyslot
|
||||
passphrase stored in kernel keyring instead. The user may load passphrase in kernel
|
||||
passphrase stored in kernel keyring instead. The user may load the passphrase in the kernel
|
||||
keyring and notify cryptsetup to read it from there later. Currently, cryptsetup
|
||||
cli supports kernel keyring for passphrase only via LUKS2 internal token
|
||||
(luks2-keyring). Library also provides a general method for device activation by
|
||||
reading passphrase from keyring: crypt_activate_by_keyring(). The key type
|
||||
(luks2-keyring). The library also provides a general method for device activation by
|
||||
reading the passphrase from the keyring: crypt_activate_by_keyring(). The key type
|
||||
for use case II) must always be 'user' since we need to read the actual key
|
||||
data from userspace unlike with VK in I). Ability to read keyslot passphrase
|
||||
from kernel keyring also allows easily auto-activate LUKS2 devices.
|
||||
data from userspace unlike with VK in I). The ability to read keyslot passphrases
|
||||
from kernel keyring also allows easy auto-activate LUKS2 devices.
|
||||
|
||||
Simple example how to use kernel keyring for keyslot passphrase:
|
||||
Simple example of how to use kernel keyring for keyslot passphrase:
|
||||
|
||||
1) create LUKS2 keyring token for keyslot 0 (in LUKS2 device/image)
|
||||
cryptsetup token add --key-description my:key -S 0 /dev/device
|
||||
@@ -43,7 +66,7 @@ cryptsetup token add --key-description my:key -S 0 /dev/device
|
||||
2) Load keyslot passphrase in user keyring
|
||||
read -s -p "Keyslot passphrase: "; echo -n $REPLY | keyctl padd user my:key @u
|
||||
|
||||
3) Activate device using passphrase stored in kernel keyring
|
||||
3) Activate the device using the passphrase stored in the kernel keyring
|
||||
cryptsetup open /dev/device my_unlocked_device
|
||||
|
||||
4a) unlink the key when no longer needed by
|
||||
@@ -52,5 +75,5 @@ keyctl unlink %user:my:key @u
|
||||
4b) or revoke it immediately by
|
||||
keyctl revoke %user:my:key
|
||||
|
||||
If cryptsetup asks for passphrase in step 3) something went wrong with keyring
|
||||
If cryptsetup asks for a passphrase in step 3) something went wrong with keyring
|
||||
activation. See --debug output then.
|
||||
|
||||
@@ -5,7 +5,7 @@ Why
|
||||
~~~
|
||||
|
||||
LUKS2 format keeps two identical copies of metadata stored consecutively
|
||||
at the head of metadata device (file or bdev). The metadata
|
||||
at the head of the metadata device (file or bdev). The metadata
|
||||
area (both copies) must be updated in a single atomic operation to avoid
|
||||
header corruption during concurrent write.
|
||||
|
||||
@@ -15,17 +15,17 @@ locking with legacy format was not so obvious as it is with the LUKSv2 format.
|
||||
|
||||
With LUKS2 the boundary between read-only and read-write is blurry and what
|
||||
used to be the exclusively read-only operation (i.e., cryptsetup open command) may
|
||||
easily become read-update operation silently without user's knowledge.
|
||||
Major feature of LUKS2 format is resilience against accidental
|
||||
easily become read-update operation silently without the user's knowledge.
|
||||
A major feature of the LUKS2 format is resilience against accidental
|
||||
corruption of metadata (i.e., partial header overwrite by parted or cfdisk
|
||||
while creating partition on mistaken block device).
|
||||
Such header corruption is detected early on header read and auto-recovery
|
||||
while creating a partition on a mistaken block device).
|
||||
Such header corruption is detected early on the header read and the auto-recovery
|
||||
procedure takes place (the corrupted header with checksum mismatch is being
|
||||
replaced by the secondary one if that one is intact).
|
||||
On current Linux systems header load operation may be triggered without user
|
||||
direct intervention for example by udev rule or from systemd service.
|
||||
Such clash of header read and auto-recovery procedure could have severe
|
||||
consequences with the worst case of having LUKS2 device unaccessible or being
|
||||
On current Linux systems header load operation may be triggered without the user
|
||||
direct intervention for example by an udev rule or from a systemd service.
|
||||
Such a clash of header read and auto-recovery procedure could have severe
|
||||
consequences with the worst case of having a LUKS2 device inaccessible or being
|
||||
broken beyond repair.
|
||||
|
||||
The whole locking of LUKSv2 device headers split into two categories depending
|
||||
@@ -36,17 +36,17 @@ I) block device
|
||||
|
||||
We perform flock() on file descriptors of files stored in a private
|
||||
directory (by default /run/lock/cryptsetup). The file name is derived
|
||||
from major:minor couple of affected block device. Note we recommend
|
||||
that access to private locking directory is supposed to be limited
|
||||
to superuser only. For this method to work the distribution needs
|
||||
from major:minor couple of the affected block device. Note we recommend
|
||||
that access to the private locking directory is supposed to be limited
|
||||
to the superuser only. For this method to work the distribution needs
|
||||
to install the locking directory with appropriate access rights.
|
||||
|
||||
II) regular files
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
First notable difference between headers stored in a file
|
||||
A first notable difference between headers stored in a file
|
||||
vs. headers stored in a block device is that headers in a file may be
|
||||
manipulated by the regular user unlike headers on block devices. Therefore
|
||||
manipulated by the regular user, unlike headers on block devices. Therefore
|
||||
we perform flock() protection on file with the luks2 header directly.
|
||||
|
||||
Limitations
|
||||
@@ -58,4 +58,40 @@ while locking is enabled.
|
||||
We do not suppress any other negative effect that two or more concurrent
|
||||
writers of the same header may cause.
|
||||
|
||||
b) The locking is not cluster aware in any way.
|
||||
b) The locking is not cluster-aware in any way.
|
||||
|
||||
Additional LUKS2 locks
|
||||
======================
|
||||
|
||||
LUKS2 reencryption device lock
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Device in LUKS2 reencryption is protected by an exclusive lock placed in the default
|
||||
locking directory. The lock's purpose is to exclude multiple processes from
|
||||
performing reencryption on the same device (identified by LUKS uuid). The lock
|
||||
is taken no matter the LUKS2 reencryption mode (online or offline).
|
||||
|
||||
LUKS2 memory hard global lock
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
An optional global lock that makes libcryptsetup serialize memory hard
|
||||
pbkdf function when deriving a key encryption key from passphrase on unlocking
|
||||
LUKS2 keyslot. The lock has to be enabled via the CRYPT_ACTIVATE_SERIALIZE_MEMORY_HARD_PBKDF
|
||||
flag. The lock is placed in the default locking directory.
|
||||
|
||||
LUKS2 OPAL lock
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
Exclusive per device lock taken when manipulating LUKS2 device configured for use with
|
||||
SED OPAL2 locking range.
|
||||
|
||||
Lock ordering
|
||||
=============
|
||||
|
||||
To avoid a deadlock following rules must apply:
|
||||
|
||||
- LUKS2 reencrytpion lock must be taken before LUKS2 OPAL lock.
|
||||
|
||||
- LUKS2 OPAL lock must be taken before LUKS2 metadata lock.
|
||||
|
||||
- LUKS2 memory hard global lock can not be used with other locks.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Doxyfile 1.9.1
|
||||
# Doxyfile 1.9.8
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Project related configuration options
|
||||
@@ -10,9 +10,9 @@ PROJECT_BRIEF = "Public cryptsetup API"
|
||||
PROJECT_LOGO =
|
||||
OUTPUT_DIRECTORY = doxygen_api_docs
|
||||
CREATE_SUBDIRS = NO
|
||||
CREATE_SUBDIRS_LEVEL = 8
|
||||
ALLOW_UNICODE_NAMES = NO
|
||||
OUTPUT_LANGUAGE = English
|
||||
OUTPUT_TEXT_DIRECTION = None
|
||||
BRIEF_MEMBER_DESC = YES
|
||||
REPEAT_BRIEF = YES
|
||||
ABBREVIATE_BRIEF =
|
||||
@@ -39,6 +39,7 @@ OPTIMIZE_OUTPUT_SLICE = NO
|
||||
EXTENSION_MAPPING =
|
||||
MARKDOWN_SUPPORT = YES
|
||||
TOC_INCLUDE_HEADINGS = 5
|
||||
MARKDOWN_ID_STYLE = DOXYGEN
|
||||
AUTOLINK_SUPPORT = YES
|
||||
BUILTIN_STL_SUPPORT = NO
|
||||
CPP_CLI_SUPPORT = NO
|
||||
@@ -52,6 +53,7 @@ INLINE_SIMPLE_STRUCTS = NO
|
||||
TYPEDEF_HIDES_STRUCT = YES
|
||||
LOOKUP_CACHE_SIZE = 0
|
||||
NUM_PROC_THREADS = 1
|
||||
TIMESTAMP = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# Build related configuration options
|
||||
#---------------------------------------------------------------------------
|
||||
@@ -72,6 +74,7 @@ INTERNAL_DOCS = NO
|
||||
CASE_SENSE_NAMES = YES
|
||||
HIDE_SCOPE_NAMES = NO
|
||||
HIDE_COMPOUND_REFERENCE= NO
|
||||
SHOW_HEADERFILE = YES
|
||||
SHOW_INCLUDE_FILES = YES
|
||||
SHOW_GROUPED_MEMB_INC = NO
|
||||
FORCE_LOCAL_INCLUDES = NO
|
||||
@@ -101,9 +104,12 @@ QUIET = NO
|
||||
WARNINGS = YES
|
||||
WARN_IF_UNDOCUMENTED = YES
|
||||
WARN_IF_DOC_ERROR = YES
|
||||
WARN_IF_INCOMPLETE_DOC = YES
|
||||
WARN_NO_PARAMDOC = NO
|
||||
WARN_IF_UNDOC_ENUM_VAL = NO
|
||||
WARN_AS_ERROR = NO
|
||||
WARN_FORMAT = "$file:$line: $text"
|
||||
WARN_LINE_FORMAT = "at line $line of file $file"
|
||||
WARN_LOGFILE =
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the input files
|
||||
@@ -111,6 +117,7 @@ WARN_LOGFILE =
|
||||
INPUT = doxygen_index.h \
|
||||
../lib/libcryptsetup.h
|
||||
INPUT_ENCODING = UTF-8
|
||||
INPUT_FILE_ENCODING =
|
||||
FILE_PATTERNS =
|
||||
RECURSIVE = NO
|
||||
EXCLUDE =
|
||||
@@ -126,6 +133,7 @@ FILTER_PATTERNS =
|
||||
FILTER_SOURCE_FILES = NO
|
||||
FILTER_SOURCE_PATTERNS =
|
||||
USE_MDFILE_AS_MAINPAGE =
|
||||
FORTRAN_COMMENT_AFTER = 72
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to source browsing
|
||||
#---------------------------------------------------------------------------
|
||||
@@ -158,15 +166,17 @@ HTML_FOOTER =
|
||||
HTML_STYLESHEET =
|
||||
HTML_EXTRA_STYLESHEET =
|
||||
HTML_EXTRA_FILES =
|
||||
HTML_COLORSTYLE = AUTO_LIGHT
|
||||
HTML_COLORSTYLE_HUE = 220
|
||||
HTML_COLORSTYLE_SAT = 100
|
||||
HTML_COLORSTYLE_GAMMA = 80
|
||||
HTML_TIMESTAMP = YES
|
||||
HTML_DYNAMIC_MENUS = YES
|
||||
HTML_DYNAMIC_SECTIONS = NO
|
||||
HTML_CODE_FOLDING = YES
|
||||
HTML_INDEX_NUM_ENTRIES = 100
|
||||
GENERATE_DOCSET = NO
|
||||
DOCSET_FEEDNAME = "Doxygen generated docs"
|
||||
DOCSET_FEEDURL =
|
||||
DOCSET_BUNDLE_ID = org.doxygen.Project
|
||||
DOCSET_PUBLISHER_ID = org.doxygen.Publisher
|
||||
DOCSET_PUBLISHER_NAME = Publisher
|
||||
@@ -177,6 +187,7 @@ GENERATE_CHI = NO
|
||||
CHM_INDEX_ENCODING =
|
||||
BINARY_TOC = NO
|
||||
TOC_EXPAND = NO
|
||||
SITEMAP_URL =
|
||||
GENERATE_QHP = NO
|
||||
QCH_FILE =
|
||||
QHP_NAMESPACE = org.doxygen.Project
|
||||
@@ -189,14 +200,16 @@ GENERATE_ECLIPSEHELP = NO
|
||||
ECLIPSE_DOC_ID = org.doxygen.Project
|
||||
DISABLE_INDEX = NO
|
||||
GENERATE_TREEVIEW = NO
|
||||
FULL_SIDEBAR = NO
|
||||
ENUM_VALUES_PER_LINE = 4
|
||||
TREEVIEW_WIDTH = 250
|
||||
EXT_LINKS_IN_WINDOW = NO
|
||||
OBFUSCATE_EMAILS = YES
|
||||
HTML_FORMULA_FORMAT = png
|
||||
FORMULA_FONTSIZE = 10
|
||||
FORMULA_TRANSPARENT = YES
|
||||
FORMULA_MACROFILE =
|
||||
USE_MATHJAX = NO
|
||||
MATHJAX_VERSION = MathJax_2
|
||||
MATHJAX_FORMAT = HTML-CSS
|
||||
MATHJAX_RELPATH = http://www.mathjax.org/mathjax
|
||||
MATHJAX_EXTENSIONS =
|
||||
@@ -227,9 +240,7 @@ PDF_HYPERLINKS = YES
|
||||
USE_PDFLATEX = YES
|
||||
LATEX_BATCHMODE = NO
|
||||
LATEX_HIDE_INDICES = NO
|
||||
LATEX_SOURCE_CODE = NO
|
||||
LATEX_BIB_STYLE = plain
|
||||
LATEX_TIMESTAMP = NO
|
||||
LATEX_EMOJI_DIRECTORY =
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the RTF output
|
||||
@@ -240,7 +251,6 @@ COMPACT_RTF = NO
|
||||
RTF_HYPERLINKS = NO
|
||||
RTF_STYLESHEET_FILE =
|
||||
RTF_EXTENSIONS_FILE =
|
||||
RTF_SOURCE_CODE = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the man page output
|
||||
#---------------------------------------------------------------------------
|
||||
@@ -261,12 +271,17 @@ XML_NS_MEMB_FILE_SCOPE = NO
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_DOCBOOK = NO
|
||||
DOCBOOK_OUTPUT = docbook
|
||||
DOCBOOK_PROGRAMLISTING = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options for the AutoGen Definitions output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_AUTOGEN_DEF = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to Sqlite3 output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_SQLITE3 = NO
|
||||
SQLITE3_OUTPUT = sqlite3
|
||||
SQLITE3_RECREATE_DB = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the Perl module output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_PERLMOD = NO
|
||||
@@ -294,15 +309,14 @@ ALLEXTERNALS = NO
|
||||
EXTERNAL_GROUPS = YES
|
||||
EXTERNAL_PAGES = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the dot tool
|
||||
# Configuration options related to diagram generator tools
|
||||
#---------------------------------------------------------------------------
|
||||
CLASS_DIAGRAMS = YES
|
||||
DIA_PATH =
|
||||
HIDE_UNDOC_RELATIONS = YES
|
||||
HAVE_DOT = NO
|
||||
DOT_NUM_THREADS = 0
|
||||
DOT_FONTNAME = Helvetica
|
||||
DOT_FONTSIZE = 10
|
||||
DOT_COMMON_ATTR = "fontname=Helvetica,fontsize=10"
|
||||
DOT_EDGE_ATTR = "labelfontname=Helvetica,labelfontsize=10"
|
||||
DOT_NODE_ATTR = "shape=box,height=0.2,width=0.4"
|
||||
DOT_FONTPATH =
|
||||
CLASS_GRAPH = YES
|
||||
COLLABORATION_GRAPH = YES
|
||||
@@ -318,18 +332,20 @@ CALL_GRAPH = NO
|
||||
CALLER_GRAPH = NO
|
||||
GRAPHICAL_HIERARCHY = YES
|
||||
DIRECTORY_GRAPH = YES
|
||||
DIR_GRAPH_MAX_DEPTH = 1
|
||||
DOT_IMAGE_FORMAT = png
|
||||
INTERACTIVE_SVG = NO
|
||||
DOT_PATH =
|
||||
DOTFILE_DIRS =
|
||||
MSCFILE_DIRS =
|
||||
DIA_PATH =
|
||||
DIAFILE_DIRS =
|
||||
PLANTUML_JAR_PATH =
|
||||
PLANTUML_CFG_FILE =
|
||||
PLANTUML_INCLUDE_PATH =
|
||||
DOT_GRAPH_MAX_NODES = 50
|
||||
MAX_DOT_GRAPH_DEPTH = 0
|
||||
DOT_TRANSPARENT = NO
|
||||
DOT_MULTI_TARGETS = NO
|
||||
GENERATE_LEGEND = YES
|
||||
DOT_CLEANUP = YES
|
||||
MSCGEN_TOOL =
|
||||
MSCFILE_DIRS =
|
||||
|
||||
@@ -1,21 +1,8 @@
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
/*
|
||||
* libcryptsetup API log example
|
||||
*
|
||||
* Copyright (C) 2011-2023 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
|
||||
* 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.
|
||||
* Copyright (C) 2011-2025 Red Hat, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -1,21 +1,8 @@
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
/*
|
||||
* libcryptsetup API - using LUKS device example
|
||||
*
|
||||
* Copyright (C) 2011-2023 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
|
||||
* 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.
|
||||
* Copyright (C) 2011-2025 Red Hat, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
202
docs/licenses/COPYING.Apache-2.0
Normal file
202
docs/licenses/COPYING.Apache-2.0
Normal file
@@ -0,0 +1,202 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
428
docs/licenses/COPYING.CC-BY-SA-4.0
Normal file
428
docs/licenses/COPYING.CC-BY-SA-4.0
Normal file
@@ -0,0 +1,428 @@
|
||||
Attribution-ShareAlike 4.0 International
|
||||
|
||||
=======================================================================
|
||||
|
||||
Creative Commons Corporation ("Creative Commons") is not a law firm and
|
||||
does not provide legal services or legal advice. Distribution of
|
||||
Creative Commons public licenses does not create a lawyer-client or
|
||||
other relationship. Creative Commons makes its licenses and related
|
||||
information available on an "as-is" basis. Creative Commons gives no
|
||||
warranties regarding its licenses, any material licensed under their
|
||||
terms and conditions, or any related information. Creative Commons
|
||||
disclaims all liability for damages resulting from their use to the
|
||||
fullest extent possible.
|
||||
|
||||
Using Creative Commons Public Licenses
|
||||
|
||||
Creative Commons public licenses provide a standard set of terms and
|
||||
conditions that creators and other rights holders may use to share
|
||||
original works of authorship and other material subject to copyright
|
||||
and certain other rights specified in the public license below. The
|
||||
following considerations are for informational purposes only, are not
|
||||
exhaustive, and do not form part of our licenses.
|
||||
|
||||
Considerations for licensors: Our public licenses are
|
||||
intended for use by those authorized to give the public
|
||||
permission to use material in ways otherwise restricted by
|
||||
copyright and certain other rights. Our licenses are
|
||||
irrevocable. Licensors should read and understand the terms
|
||||
and conditions of the license they choose before applying it.
|
||||
Licensors should also secure all rights necessary before
|
||||
applying our licenses so that the public can reuse the
|
||||
material as expected. Licensors should clearly mark any
|
||||
material not subject to the license. This includes other CC-
|
||||
licensed material, or material used under an exception or
|
||||
limitation to copyright. More considerations for licensors:
|
||||
wiki.creativecommons.org/Considerations_for_licensors
|
||||
|
||||
Considerations for the public: By using one of our public
|
||||
licenses, a licensor grants the public permission to use the
|
||||
licensed material under specified terms and conditions. If
|
||||
the licensor's permission is not necessary for any reason--for
|
||||
example, because of any applicable exception or limitation to
|
||||
copyright--then that use is not regulated by the license. Our
|
||||
licenses grant only permissions under copyright and certain
|
||||
other rights that a licensor has authority to grant. Use of
|
||||
the licensed material may still be restricted for other
|
||||
reasons, including because others have copyright or other
|
||||
rights in the material. A licensor may make special requests,
|
||||
such as asking that all changes be marked or described.
|
||||
Although not required by our licenses, you are encouraged to
|
||||
respect those requests where reasonable. More considerations
|
||||
for the public:
|
||||
wiki.creativecommons.org/Considerations_for_licensees
|
||||
|
||||
=======================================================================
|
||||
|
||||
Creative Commons Attribution-ShareAlike 4.0 International Public
|
||||
License
|
||||
|
||||
By exercising the Licensed Rights (defined below), You accept and agree
|
||||
to be bound by the terms and conditions of this Creative Commons
|
||||
Attribution-ShareAlike 4.0 International Public License ("Public
|
||||
License"). To the extent this Public License may be interpreted as a
|
||||
contract, You are granted the Licensed Rights in consideration of Your
|
||||
acceptance of these terms and conditions, and the Licensor grants You
|
||||
such rights in consideration of benefits the Licensor receives from
|
||||
making the Licensed Material available under these terms and
|
||||
conditions.
|
||||
|
||||
|
||||
Section 1 -- Definitions.
|
||||
|
||||
a. Adapted Material means material subject to Copyright and Similar
|
||||
Rights that is derived from or based upon the Licensed Material
|
||||
and in which the Licensed Material is translated, altered,
|
||||
arranged, transformed, or otherwise modified in a manner requiring
|
||||
permission under the Copyright and Similar Rights held by the
|
||||
Licensor. For purposes of this Public License, where the Licensed
|
||||
Material is a musical work, performance, or sound recording,
|
||||
Adapted Material is always produced where the Licensed Material is
|
||||
synched in timed relation with a moving image.
|
||||
|
||||
b. Adapter's License means the license You apply to Your Copyright
|
||||
and Similar Rights in Your contributions to Adapted Material in
|
||||
accordance with the terms and conditions of this Public License.
|
||||
|
||||
c. BY-SA Compatible License means a license listed at
|
||||
creativecommons.org/compatiblelicenses, approved by Creative
|
||||
Commons as essentially the equivalent of this Public License.
|
||||
|
||||
d. Copyright and Similar Rights means copyright and/or similar rights
|
||||
closely related to copyright including, without limitation,
|
||||
performance, broadcast, sound recording, and Sui Generis Database
|
||||
Rights, without regard to how the rights are labeled or
|
||||
categorized. For purposes of this Public License, the rights
|
||||
specified in Section 2(b)(1)-(2) are not Copyright and Similar
|
||||
Rights.
|
||||
|
||||
e. Effective Technological Measures means those measures that, in the
|
||||
absence of proper authority, may not be circumvented under laws
|
||||
fulfilling obligations under Article 11 of the WIPO Copyright
|
||||
Treaty adopted on December 20, 1996, and/or similar international
|
||||
agreements.
|
||||
|
||||
f. Exceptions and Limitations means fair use, fair dealing, and/or
|
||||
any other exception or limitation to Copyright and Similar Rights
|
||||
that applies to Your use of the Licensed Material.
|
||||
|
||||
g. License Elements means the license attributes listed in the name
|
||||
of a Creative Commons Public License. The License Elements of this
|
||||
Public License are Attribution and ShareAlike.
|
||||
|
||||
h. Licensed Material means the artistic or literary work, database,
|
||||
or other material to which the Licensor applied this Public
|
||||
License.
|
||||
|
||||
i. Licensed Rights means the rights granted to You subject to the
|
||||
terms and conditions of this Public License, which are limited to
|
||||
all Copyright and Similar Rights that apply to Your use of the
|
||||
Licensed Material and that the Licensor has authority to license.
|
||||
|
||||
j. Licensor means the individual(s) or entity(ies) granting rights
|
||||
under this Public License.
|
||||
|
||||
k. Share means to provide material to the public by any means or
|
||||
process that requires permission under the Licensed Rights, such
|
||||
as reproduction, public display, public performance, distribution,
|
||||
dissemination, communication, or importation, and to make material
|
||||
available to the public including in ways that members of the
|
||||
public may access the material from a place and at a time
|
||||
individually chosen by them.
|
||||
|
||||
l. Sui Generis Database Rights means rights other than copyright
|
||||
resulting from Directive 96/9/EC of the European Parliament and of
|
||||
the Council of 11 March 1996 on the legal protection of databases,
|
||||
as amended and/or succeeded, as well as other essentially
|
||||
equivalent rights anywhere in the world.
|
||||
|
||||
m. You means the individual or entity exercising the Licensed Rights
|
||||
under this Public License. Your has a corresponding meaning.
|
||||
|
||||
|
||||
Section 2 -- Scope.
|
||||
|
||||
a. License grant.
|
||||
|
||||
1. Subject to the terms and conditions of this Public License,
|
||||
the Licensor hereby grants You a worldwide, royalty-free,
|
||||
non-sublicensable, non-exclusive, irrevocable license to
|
||||
exercise the Licensed Rights in the Licensed Material to:
|
||||
|
||||
a. reproduce and Share the Licensed Material, in whole or
|
||||
in part; and
|
||||
|
||||
b. produce, reproduce, and Share Adapted Material.
|
||||
|
||||
2. Exceptions and Limitations. For the avoidance of doubt, where
|
||||
Exceptions and Limitations apply to Your use, this Public
|
||||
License does not apply, and You do not need to comply with
|
||||
its terms and conditions.
|
||||
|
||||
3. Term. The term of this Public License is specified in Section
|
||||
6(a).
|
||||
|
||||
4. Media and formats; technical modifications allowed. The
|
||||
Licensor authorizes You to exercise the Licensed Rights in
|
||||
all media and formats whether now known or hereafter created,
|
||||
and to make technical modifications necessary to do so. The
|
||||
Licensor waives and/or agrees not to assert any right or
|
||||
authority to forbid You from making technical modifications
|
||||
necessary to exercise the Licensed Rights, including
|
||||
technical modifications necessary to circumvent Effective
|
||||
Technological Measures. For purposes of this Public License,
|
||||
simply making modifications authorized by this Section 2(a)
|
||||
(4) never produces Adapted Material.
|
||||
|
||||
5. Downstream recipients.
|
||||
|
||||
a. Offer from the Licensor -- Licensed Material. Every
|
||||
recipient of the Licensed Material automatically
|
||||
receives an offer from the Licensor to exercise the
|
||||
Licensed Rights under the terms and conditions of this
|
||||
Public License.
|
||||
|
||||
b. Additional offer from the Licensor -- Adapted Material.
|
||||
Every recipient of Adapted Material from You
|
||||
automatically receives an offer from the Licensor to
|
||||
exercise the Licensed Rights in the Adapted Material
|
||||
under the conditions of the Adapter's License You apply.
|
||||
|
||||
c. No downstream restrictions. You may not offer or impose
|
||||
any additional or different terms or conditions on, or
|
||||
apply any Effective Technological Measures to, the
|
||||
Licensed Material if doing so restricts exercise of the
|
||||
Licensed Rights by any recipient of the Licensed
|
||||
Material.
|
||||
|
||||
6. No endorsement. Nothing in this Public License constitutes or
|
||||
may be construed as permission to assert or imply that You
|
||||
are, or that Your use of the Licensed Material is, connected
|
||||
with, or sponsored, endorsed, or granted official status by,
|
||||
the Licensor or others designated to receive attribution as
|
||||
provided in Section 3(a)(1)(A)(i).
|
||||
|
||||
b. Other rights.
|
||||
|
||||
1. Moral rights, such as the right of integrity, are not
|
||||
licensed under this Public License, nor are publicity,
|
||||
privacy, and/or other similar personality rights; however, to
|
||||
the extent possible, the Licensor waives and/or agrees not to
|
||||
assert any such rights held by the Licensor to the limited
|
||||
extent necessary to allow You to exercise the Licensed
|
||||
Rights, but not otherwise.
|
||||
|
||||
2. Patent and trademark rights are not licensed under this
|
||||
Public License.
|
||||
|
||||
3. To the extent possible, the Licensor waives any right to
|
||||
collect royalties from You for the exercise of the Licensed
|
||||
Rights, whether directly or through a collecting society
|
||||
under any voluntary or waivable statutory or compulsory
|
||||
licensing scheme. In all other cases the Licensor expressly
|
||||
reserves any right to collect such royalties.
|
||||
|
||||
|
||||
Section 3 -- License Conditions.
|
||||
|
||||
Your exercise of the Licensed Rights is expressly made subject to the
|
||||
following conditions.
|
||||
|
||||
a. Attribution.
|
||||
|
||||
1. If You Share the Licensed Material (including in modified
|
||||
form), You must:
|
||||
|
||||
a. retain the following if it is supplied by the Licensor
|
||||
with the Licensed Material:
|
||||
|
||||
i. identification of the creator(s) of the Licensed
|
||||
Material and any others designated to receive
|
||||
attribution, in any reasonable manner requested by
|
||||
the Licensor (including by pseudonym if
|
||||
designated);
|
||||
|
||||
ii. a copyright notice;
|
||||
|
||||
iii. a notice that refers to this Public License;
|
||||
|
||||
iv. a notice that refers to the disclaimer of
|
||||
warranties;
|
||||
|
||||
v. a URI or hyperlink to the Licensed Material to the
|
||||
extent reasonably practicable;
|
||||
|
||||
b. indicate if You modified the Licensed Material and
|
||||
retain an indication of any previous modifications; and
|
||||
|
||||
c. indicate the Licensed Material is licensed under this
|
||||
Public License, and include the text of, or the URI or
|
||||
hyperlink to, this Public License.
|
||||
|
||||
2. You may satisfy the conditions in Section 3(a)(1) in any
|
||||
reasonable manner based on the medium, means, and context in
|
||||
which You Share the Licensed Material. For example, it may be
|
||||
reasonable to satisfy the conditions by providing a URI or
|
||||
hyperlink to a resource that includes the required
|
||||
information.
|
||||
|
||||
3. If requested by the Licensor, You must remove any of the
|
||||
information required by Section 3(a)(1)(A) to the extent
|
||||
reasonably practicable.
|
||||
|
||||
b. ShareAlike.
|
||||
|
||||
In addition to the conditions in Section 3(a), if You Share
|
||||
Adapted Material You produce, the following conditions also apply.
|
||||
|
||||
1. The Adapter's License You apply must be a Creative Commons
|
||||
license with the same License Elements, this version or
|
||||
later, or a BY-SA Compatible License.
|
||||
|
||||
2. You must include the text of, or the URI or hyperlink to, the
|
||||
Adapter's License You apply. You may satisfy this condition
|
||||
in any reasonable manner based on the medium, means, and
|
||||
context in which You Share Adapted Material.
|
||||
|
||||
3. You may not offer or impose any additional or different terms
|
||||
or conditions on, or apply any Effective Technological
|
||||
Measures to, Adapted Material that restrict exercise of the
|
||||
rights granted under the Adapter's License You apply.
|
||||
|
||||
|
||||
Section 4 -- Sui Generis Database Rights.
|
||||
|
||||
Where the Licensed Rights include Sui Generis Database Rights that
|
||||
apply to Your use of the Licensed Material:
|
||||
|
||||
a. for the avoidance of doubt, Section 2(a)(1) grants You the right
|
||||
to extract, reuse, reproduce, and Share all or a substantial
|
||||
portion of the contents of the database;
|
||||
|
||||
b. if You include all or a substantial portion of the database
|
||||
contents in a database in which You have Sui Generis Database
|
||||
Rights, then the database in which You have Sui Generis Database
|
||||
Rights (but not its individual contents) is Adapted Material,
|
||||
including for purposes of Section 3(b); and
|
||||
|
||||
c. You must comply with the conditions in Section 3(a) if You Share
|
||||
all or a substantial portion of the contents of the database.
|
||||
|
||||
For the avoidance of doubt, this Section 4 supplements and does not
|
||||
replace Your obligations under this Public License where the Licensed
|
||||
Rights include other Copyright and Similar Rights.
|
||||
|
||||
|
||||
Section 5 -- Disclaimer of Warranties and Limitation of Liability.
|
||||
|
||||
a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE
|
||||
EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS
|
||||
AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF
|
||||
ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS,
|
||||
IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION,
|
||||
WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS,
|
||||
ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT
|
||||
KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT
|
||||
ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.
|
||||
|
||||
b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE
|
||||
TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION,
|
||||
NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT,
|
||||
INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES,
|
||||
COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR
|
||||
USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN
|
||||
ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR
|
||||
DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR
|
||||
IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.
|
||||
|
||||
c. The disclaimer of warranties and limitation of liability provided
|
||||
above shall be interpreted in a manner that, to the extent
|
||||
possible, most closely approximates an absolute disclaimer and
|
||||
waiver of all liability.
|
||||
|
||||
|
||||
Section 6 -- Term and Termination.
|
||||
|
||||
a. This Public License applies for the term of the Copyright and
|
||||
Similar Rights licensed here. However, if You fail to comply with
|
||||
this Public License, then Your rights under this Public License
|
||||
terminate automatically.
|
||||
|
||||
b. Where Your right to use the Licensed Material has terminated under
|
||||
Section 6(a), it reinstates:
|
||||
|
||||
1. automatically as of the date the violation is cured, provided
|
||||
it is cured within 30 days of Your discovery of the
|
||||
violation; or
|
||||
|
||||
2. upon express reinstatement by the Licensor.
|
||||
|
||||
For the avoidance of doubt, this Section 6(b) does not affect any
|
||||
right the Licensor may have to seek remedies for Your violations
|
||||
of this Public License.
|
||||
|
||||
c. For the avoidance of doubt, the Licensor may also offer the
|
||||
Licensed Material under separate terms or conditions or stop
|
||||
distributing the Licensed Material at any time; however, doing so
|
||||
will not terminate this Public License.
|
||||
|
||||
d. Sections 1, 5, 6, 7, and 8 survive termination of this Public
|
||||
License.
|
||||
|
||||
|
||||
Section 7 -- Other Terms and Conditions.
|
||||
|
||||
a. The Licensor shall not be bound by any additional or different
|
||||
terms or conditions communicated by You unless expressly agreed.
|
||||
|
||||
b. Any arrangements, understandings, or agreements regarding the
|
||||
Licensed Material not stated herein are separate from and
|
||||
independent of the terms and conditions of this Public License.
|
||||
|
||||
|
||||
Section 8 -- Interpretation.
|
||||
|
||||
a. For the avoidance of doubt, this Public License does not, and
|
||||
shall not be interpreted to, reduce, limit, restrict, or impose
|
||||
conditions on any use of the Licensed Material that could lawfully
|
||||
be made without permission under this Public License.
|
||||
|
||||
b. To the extent possible, if any provision of this Public License is
|
||||
deemed unenforceable, it shall be automatically reformed to the
|
||||
minimum extent necessary to make it enforceable. If the provision
|
||||
cannot be reformed, it shall be severed from this Public License
|
||||
without affecting the enforceability of the remaining terms and
|
||||
conditions.
|
||||
|
||||
c. No term or condition of this Public License will be waived and no
|
||||
failure to comply consented to unless expressly agreed to by the
|
||||
Licensor.
|
||||
|
||||
d. Nothing in this Public License constitutes or may be interpreted
|
||||
as a limitation upon, or waiver of, any privileges and immunities
|
||||
that apply to the Licensor or You, including from the legal
|
||||
processes of any jurisdiction or authority.
|
||||
|
||||
|
||||
=======================================================================
|
||||
|
||||
Creative Commons is not a party to its public
|
||||
licenses. Notwithstanding, Creative Commons may elect to apply one of
|
||||
its public licenses to material it publishes and in those instances
|
||||
will be considered the “Licensor.” The text of the Creative Commons
|
||||
public licenses is dedicated to the public domain under the CC0 Public
|
||||
Domain Dedication. Except for the limited purpose of indicating that
|
||||
material is shared under a Creative Commons public license or as
|
||||
otherwise permitted by the Creative Commons policies published at
|
||||
creativecommons.org/policies, Creative Commons does not authorize the
|
||||
use of the trademark "Creative Commons" or any other trademark or logo
|
||||
of Creative Commons without its prior written consent including,
|
||||
without limitation, in connection with any unauthorized modifications
|
||||
to any of its public licenses or any other arrangements,
|
||||
understandings, or agreements concerning use of licensed material. For
|
||||
the avoidance of doubt, this paragraph does not form part of the
|
||||
public licenses.
|
||||
|
||||
Creative Commons may be contacted at creativecommons.org.
|
||||
|
||||
@@ -0,0 +1,354 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
||||
|
||||
-----
|
||||
In addition, as a special exception, the copyright holders give
|
||||
permission to link the code of portions of this program with the
|
||||
OpenSSL library under certain conditions as described in each
|
||||
individual source file, and distribute linked combinations
|
||||
including the two.
|
||||
|
||||
You must obey the GNU General Public License in all respects
|
||||
for all of the code used other than OpenSSL. If you modify
|
||||
file(s) with this exception, you may extend this exception to your
|
||||
version of the file(s), but you are not obligated to do so. If you
|
||||
do not wish to do so, delete this exception statement from your
|
||||
version. If you delete this exception statement from all source
|
||||
files in the program, then also delete it here.
|
||||
Binary file not shown.
@@ -1,6 +1,6 @@
|
||||
Cryptsetup 2.7.0-rc0 Release Notes
|
||||
==================================
|
||||
Stable release candidate with new features and bug fixes.
|
||||
Cryptsetup 2.7.0 Release Notes
|
||||
==============================
|
||||
Stable release with new features and bug fixes.
|
||||
|
||||
Changes since version 2.6.1
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
@@ -47,15 +47,14 @@ Changes since version 2.6.1
|
||||
encryption (--hw-opal option) or without the software layer
|
||||
(--hw-opal-only option).
|
||||
You can see the configured segment parameters in the luksDump command.
|
||||
Note: formal specification of OPAL LUKS2 segment metadata will be added
|
||||
in the next release candidate. LUKS2 devices with OPAL segments set
|
||||
a new requirement flag in the LUKS2 header to prevent older cryptsetup
|
||||
metadata manipulation. Do not use hardware-only encryption if you do
|
||||
not fully trust your hardware vendor.
|
||||
LUKS2 devices with OPAL segments set a new requirement flag in
|
||||
the LUKS2 header to prevent older cryptsetup metadata manipulation.
|
||||
Do not use hardware-only encryption if you do not fully trust your
|
||||
hardware vendor.
|
||||
|
||||
Compatibility notes:
|
||||
- Linux kernel SED interface does NOT work through USB external
|
||||
adapters due to the mising compatibility layer in Linux USB storage
|
||||
adapters due to the missing compatibility layer in Linux USB storage
|
||||
drivers (even if USB hardware itself can support OPAL commands).
|
||||
- other TCG security subsystems like Ruby or Pyrite are not
|
||||
supported. Note that many drives support only Pyrite subsystem that
|
||||
@@ -63,7 +62,6 @@ Changes since version 2.6.1
|
||||
- compatibility among OPAL-enabled drives is often very problematic,
|
||||
specifically for older drives. Many drives have bugs in the firmware
|
||||
that make the Linux kernel interface unusable.
|
||||
- unlocking key for OPAL remains in memory even after luksSuspend
|
||||
- if you forget the OPAL admin password, the only way to recover is
|
||||
the full drive factory reset through the PSID key (usually printed
|
||||
on the drive itself) that wipes all data on the drive (not only the
|
||||
@@ -186,9 +184,6 @@ Changes since version 2.6.1
|
||||
These options are intended to be used for integration with other
|
||||
systems for automation.
|
||||
|
||||
Note: the API will slightly change in the next release candidate
|
||||
(active reencryption will need to setup old and new keys together).
|
||||
|
||||
Users can now use the volume key (not passphrase) stored in arbitrary
|
||||
kernel keyring and directly use it in particular cryptsetup commands
|
||||
with --volume-key-keyring option. The keyring can use various policies
|
||||
@@ -205,7 +200,7 @@ Changes since version 2.6.1
|
||||
<keyring_description>::<key_description>.
|
||||
The <keyring_description> contains the existing kernel keyring
|
||||
description (numeric id or keyctl format). The <keyring_description>
|
||||
may be optionaly prefixed with "%:" or "%keyring:". The string "::" is
|
||||
may be optionally prefixed with "%:" or "%keyring:". The string "::" is
|
||||
a delimiter that separates keyring and key descriptions.
|
||||
The <key_description> has the same syntax as used in the
|
||||
--volume-key-keyring option.
|
||||
@@ -264,9 +259,7 @@ Changes since version 2.6.1
|
||||
option is specified.
|
||||
|
||||
* Properly report if the dm-verity device cannot be activated due to
|
||||
the inability to verify the signed root hash.
|
||||
|
||||
If the kernel returns ENOKEY, it is properly propagated.
|
||||
the inability to verify the signed root hash (ENOKEY).
|
||||
|
||||
* Fix to check passphrase for selected keyslot only when adding
|
||||
new keyslot.
|
||||
@@ -305,9 +298,9 @@ Changes since version 2.6.1
|
||||
* Fix wipe operation that overwrites the whole device if used for LUKS2
|
||||
header with no keyslot area.
|
||||
|
||||
Formatting a LUKS2 device with no defined keyslots area is a very
|
||||
specific operation, and the code now properly recognizes such
|
||||
configuration.
|
||||
Formatting a LUKS2 device with no defined keyslots area is a very
|
||||
specific operation, and the code now properly recognizes such
|
||||
configuration.
|
||||
|
||||
* Fix luksErase to work with detached LUKS header.
|
||||
|
||||
@@ -376,6 +369,12 @@ Changes since version 2.6.1
|
||||
Argon2 has been available since version 1.10, but we need version 1.11,
|
||||
which will allow empty passwords.
|
||||
|
||||
* Used Argon2 PBKDF implementation is now reported in debug mode
|
||||
in the cryptographic backend version. For native support in
|
||||
OpenSSL 3.2 or libgcrypt 1.11, "argon2" is displayed.
|
||||
If libargon2 is used, "cryptsetup libargon2" (for embedded
|
||||
library) or "external libargon2" is displayed.
|
||||
|
||||
* Link only libcrypto from OpenSSL.
|
||||
|
||||
This reduces dependencies as other OpenSSL libraries are not needed.
|
||||
@@ -404,6 +403,9 @@ Changes since version 2.6.1
|
||||
and possibly corrupt data if the user also tries to modify the
|
||||
underlying device.
|
||||
|
||||
* Update keyring and locking documentation and LUKS2 specification
|
||||
for OPAL2 support.
|
||||
|
||||
Libcryptsetup API extensions
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
The libcryptsetup API is backward compatible for all existing symbols.
|
||||
30
docs/v2.7.1-ReleaseNotes
Normal file
30
docs/v2.7.1-ReleaseNotes
Normal file
@@ -0,0 +1,30 @@
|
||||
Cryptsetup 2.7.1 Release Notes
|
||||
==============================
|
||||
Stable bug-fix release with minor extensions.
|
||||
|
||||
All users of cryptsetup 2.7.0 should upgrade to this version.
|
||||
|
||||
Changes since version 2.7.0
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* Fix interrupted LUKS1 decryption resume.
|
||||
With the replacement of the cryptsetup-reencrypt tool by the cryptsetup
|
||||
reencrypt command, resuming the interrupted LUKS1 decryption operation
|
||||
could fail. LUKS2 was not affected.
|
||||
|
||||
* Allow --link-vk-to-keyring with --test-passphrase option.
|
||||
This option allows uploading the volume key in a user-specified kernel
|
||||
keyring without activating the device.
|
||||
|
||||
* Fix crash when --active-name was used in decryption initialization.
|
||||
|
||||
* Updates and changes to man pages, including indentation, sorting options
|
||||
alphabetically, fixing mistakes in crypt_set_keyring_to_link, and fixing
|
||||
some typos.
|
||||
|
||||
* Fix compilation with libargon2 when --disable-internal-argon2 was used.
|
||||
|
||||
* Do not require installed argon2.h header and never compile internal
|
||||
libargon2 code if the crypto library directly supports Argon2.
|
||||
|
||||
* Fixes to regression tests to support older Linux distributions.
|
||||
31
docs/v2.7.2-ReleaseNotes
Normal file
31
docs/v2.7.2-ReleaseNotes
Normal file
@@ -0,0 +1,31 @@
|
||||
Cryptsetup 2.7.2 Release Notes
|
||||
==============================
|
||||
Stable bug-fix release.
|
||||
|
||||
All users of cryptsetup 2.7 should upgrade to this version.
|
||||
|
||||
Changes since version 2.7.1
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
* Fix activation of OPAL-only encrypted LUKS device with tokens.
|
||||
The issue was caused by an invalid volume key check (assert)
|
||||
that is impossible without software encryption.
|
||||
|
||||
* Fix formatting of OPAL devices with 4096-byte sector size.
|
||||
|
||||
* Fix incorrect OPAL locking range alignment calculation if used
|
||||
over an unaligned device partition.
|
||||
|
||||
* Add --hw-opal-factory-reset option description to the manual page.
|
||||
|
||||
* Do not check the passphrase quality for OPAL Admin PIN,
|
||||
as this passphrase already exists.
|
||||
|
||||
* Update license for FAQ document to CC BY-SA 4.0.
|
||||
|
||||
NOTE: Please note that with OPAL-only (--hw-opal-only) encryption,
|
||||
the configured OPAL administrator PIN (passphrase) allows unlocking
|
||||
all configured locking ranges without LUKS keyslot decryption
|
||||
(without knowledge of LUKS passphrase).
|
||||
Because of many observed problems with compatibility, cryptsetup
|
||||
currently DOES NOT use OPAL single-user mode, which would allow such
|
||||
decoupling of OPAL admin PIN access.
|
||||
114
docs/v2.7.3-ReleaseNotes
Normal file
114
docs/v2.7.3-ReleaseNotes
Normal file
@@ -0,0 +1,114 @@
|
||||
Cryptsetup 2.7.3 Release Notes
|
||||
==============================
|
||||
Stable bug-fix release with security fixes.
|
||||
|
||||
All users of cryptsetup 2.7 must upgrade to this version.
|
||||
|
||||
Changes since version 2.7.2
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* Do not allow formatting LUKS2 with Opal SED (hardware encryption)
|
||||
if the reported logical sector size for the block device and Opal
|
||||
encryption logical block differs.
|
||||
|
||||
Such a configuration can lead to a partially encrypted Opal locking
|
||||
range or data destruction following the expected locking range.
|
||||
|
||||
Some NVMe drives support multiple LBAF profiles (typically supporting
|
||||
512-byte and 4096-byte sector size). Some broken Opal NVMe firmware can
|
||||
report bogus encryption size that disagrees with real used sector size.
|
||||
This usually happens after low-level NVMe reformatting (LBAF profile
|
||||
change with nvme utility) to different sector size.
|
||||
Moreover, some firmware versions do not properly reset this even after
|
||||
explicit PSID revert.
|
||||
|
||||
Cryptsetup calculates the Opal locking range using the reported block
|
||||
size in Opal geometry ioctl. Unfortunately, the broken firmware drive
|
||||
internally uses the logical block size of the block device, which can
|
||||
differ. This can lead to two possible situations:
|
||||
|
||||
- Opal reports a smaller block size (512-byte) while the drive uses
|
||||
a 4096-byte sector. The configured locking range is then much larger,
|
||||
destroying data following the expected locking range setting.
|
||||
|
||||
- Opal reports a larger block size (4096-byte) while the drive uses
|
||||
a 512-byte sector. The configured locking range is then much smaller,
|
||||
leaving the remaining space in the locking range unencrypted (violating
|
||||
the confidentiality of data).
|
||||
|
||||
Cryptsetup now detects this discrepancy and disallows LUKS2 format with
|
||||
Opal hardware encryption in such a case.
|
||||
|
||||
For already formatted devices, you will see this warning:
|
||||
"Bogus OPAL logical block size differs from device block size."
|
||||
|
||||
If you also used software encryption (dm-crypt over Opal), data will
|
||||
still be fully encrypted with software dm-crypt.
|
||||
With hw-only encryption, your configuration is probably already broken
|
||||
(insecure or accessing data beyond the assigned area).
|
||||
|
||||
Note that this is caused by bad firmware (seen with multiple vendors),
|
||||
and the problem was reported, at least for drives we have access to.
|
||||
|
||||
* Fixes to wiping LUKS2 headers after Opal locking area erase.
|
||||
|
||||
As the hardware locking range is destroyed (cryptsetup erase command),
|
||||
the LUKS2 header is no longer usable and was partially wiped.
|
||||
Now the code fully wipes also the secondary header, as the previous
|
||||
code wiped only the primary LUKS area.
|
||||
|
||||
Note that this is an exception, as the normal erase command wipes only
|
||||
the keyslots, keeping the LUKS2 header in place. With Opal encryption,
|
||||
the data segment is no longer valid, so the whole LUKS2 header is no
|
||||
longer usable.
|
||||
|
||||
* Mention the need for possible PSID revert before Opal format for some
|
||||
drives (man page).
|
||||
|
||||
* Fix Bitlocker-compatible code to ignore newly seen metadata entries.
|
||||
|
||||
Recent Windows OS versions started to include new (undocumented)
|
||||
metadata entries in Bitlocker. These entries are now quietly ignored,
|
||||
allowing Bitlocker images to open with cryptsetup again.
|
||||
|
||||
* Fix interactive query retry if LUKS2 unbound keyslot is present.
|
||||
|
||||
If an unbound keyslot is present, the password query retry count is
|
||||
now properly applied.
|
||||
|
||||
* Detect unsupported zoned devices for LUKS header devices.
|
||||
|
||||
Zoned devices cannot be written with direct-io and used for LUKS header
|
||||
logic in general. Code now rejects placing the LUKS header on a zoned
|
||||
device, while you can still create a detached header and use a zoned
|
||||
device for encrypted data.
|
||||
|
||||
* Allow "capi" cipher format for benchmark command and fix parsing
|
||||
of plain IV in "capi" format.
|
||||
|
||||
Some ciphers can be specified only in Linux kernel crypto notation
|
||||
(in short, "capi"). Code now allows this format also for benchmark,
|
||||
for example, "benchmark -c capi:xts\(aes\)-plain64"
|
||||
(that is equivalent to -c aes-xts-plain64).
|
||||
|
||||
* Add support for HCTR2 encryption mode.
|
||||
|
||||
The HCTR2 encryption mode was added to the Linux kernel for fscrypt,
|
||||
but as it is a length-preserving mode (with sector tweak), it can be
|
||||
easily used for disk encryption, too.
|
||||
The mode has the same property as wide modes (any change is propagated
|
||||
to the whole sector instead of only one block as in XTS mode).
|
||||
|
||||
As it needs a larger initialization vector (32 bytes), we need to add
|
||||
an exception in the userspace format code.
|
||||
You can now use --cipher aes-hctr2-plain64 for the format operation.
|
||||
|
||||
* Source code now uses SPDX license identifiers instead of full
|
||||
license preambles.
|
||||
|
||||
* Fix missing includes for cryptographic backend that could cause
|
||||
compilation errors for some systems.
|
||||
|
||||
* Fix tests to work correctly in FIPS mode with recent OpenSSL 3.2.
|
||||
|
||||
* Fix various (mostly false positive) issues detected by Coverity.
|
||||
62
docs/v2.7.4-ReleaseNotes
Normal file
62
docs/v2.7.4-ReleaseNotes
Normal file
@@ -0,0 +1,62 @@
|
||||
Cryptsetup 2.7.4 Release Notes
|
||||
==============================
|
||||
Stable bug-fix release.
|
||||
|
||||
All users of cryptsetup 2.7 should upgrade to this version.
|
||||
|
||||
Changes since version 2.7.3
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* Detect device busy failure for device-mapper table-referenced devices.
|
||||
|
||||
Some device-mapper ioctl failures can disappear in libdevmapper,
|
||||
causing the libcryptsetup wrapper to return an invalid error (EINVAL)
|
||||
instead of EEXIST or EBUSY. One such case is when there is a device
|
||||
creation race, and the device-mapper device name is created, but
|
||||
the following mapping table load fails. This can happen because some
|
||||
block devices used in table mapping have already been claimed by
|
||||
another process (the kernel needs exclusive access).
|
||||
|
||||
The kernel ioctl properly returns EBUSY; this errno is lost in
|
||||
libdevmapper (dm_task_get_errno returns 0). It should be fixed by
|
||||
libdevmapper in the future.
|
||||
|
||||
Such behavior was seen in the systemd way of handling dm-verity
|
||||
devices. With these changes, the code should react for EEXIST and
|
||||
EBUSY, as another process has already activated the device.
|
||||
|
||||
Code calling libcryptsetup also must not check the underlying device
|
||||
with an exclusive open flag (O_EXCL). Otherwise, it could cause a race
|
||||
in the kernel device-mapper, resulting in no process succeeding device
|
||||
activation (see also CRYPT_ACTIVATE_SHARED flag below).
|
||||
|
||||
* Fix shared activation for dm-verity devices.
|
||||
|
||||
The CRYPT_ACTIVATE_SHARED flag was silently ignored when activating
|
||||
dm-verity devices. Dm-verity shared activation is generally safe
|
||||
since all verity devices are read-only.
|
||||
|
||||
The shared flag is a way to skip the exclusive access check for the
|
||||
device, allowing it to create multiple mappings with the same device or
|
||||
properly handle a racy concurrent activation of devices with the same
|
||||
name from different processes.
|
||||
|
||||
* Add --shared option for veritysetup open action.
|
||||
|
||||
The option allows the data device to be used in multiple device-mapper
|
||||
table mappings (skip exclusive access check) or to allow concurrent
|
||||
dm-verity device activation of the same device (only one process
|
||||
succeeds in this case; the other will return EEXIST or EBUSY).
|
||||
|
||||
* Do not use exclusive flag for the allocated backing loop files.
|
||||
|
||||
Using this flag is an undefined operation for opening an existing file.
|
||||
The flag should be used only for allocated loop (block) devices.
|
||||
|
||||
* Fixes for problems found by static analyzers and Valgrind.
|
||||
|
||||
These include fixes for non-default libgcrypt, NSS, and Nettle
|
||||
cryptographic backends, buffer operations to avoid partial read/write,
|
||||
and several other workarounds for mostly false positive warnings.
|
||||
|
||||
* Fixes to tests and CI scripts.
|
||||
23
docs/v2.7.5-ReleaseNotes
Normal file
23
docs/v2.7.5-ReleaseNotes
Normal file
@@ -0,0 +1,23 @@
|
||||
Cryptsetup 2.7.5 Release Notes
|
||||
==============================
|
||||
Stable bug-fix release.
|
||||
|
||||
All users of cryptsetup 2.7 must upgrade to this version.
|
||||
|
||||
Changes since version 2.7.4
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
* Fix possible online reencryption data corruption (only in 2.7.x).
|
||||
|
||||
In some situations (initializing a suspended device-mapper device),
|
||||
cryptsetup disabled direct-io device access. This caused unsafe
|
||||
online reencryption operations that could lead to data corruption.
|
||||
The code now adds strict checks (and aborts the operation) and
|
||||
changes direct-io detection code to prevent data corruption.
|
||||
|
||||
* Fix a clang compilation error in SSH token plugin.
|
||||
|
||||
As clang linker treats missing symbols as errors, the linker phase
|
||||
for the SSH token failed as the optional cryptsetup_token_buffer_free
|
||||
was not defined.
|
||||
|
||||
* Fix crypto backend initialization in crypt_format_luks2_opal API call.
|
||||
328
docs/v2.8.0-ReleaseNotes
Normal file
328
docs/v2.8.0-ReleaseNotes
Normal file
@@ -0,0 +1,328 @@
|
||||
Cryptsetup 2.8.0 Release Notes
|
||||
==============================
|
||||
Stable release with new features and bug fixes
|
||||
|
||||
All users of cryptsetup 2.7 must upgrade to this version.
|
||||
|
||||
Changes since version 2.7.5
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* Introduce support for inline mode (use HW sectors with additional hardware metadata space).
|
||||
|
||||
Some enterprise NVMe drives allow formatting sector size with additional metadata space,
|
||||
for example, sector size 4096 bytes + 64 bytes for metadata.
|
||||
We hope common firmware will soon support such features in more recent models.
|
||||
|
||||
If this metadata space is available (not internally used by a data integrity profile),
|
||||
it removes the need to use the dm-integrity layer for sector metadata allocation.
|
||||
This means that the performance bottleneck caused by the dm-integrity journal is eliminated.
|
||||
|
||||
Note: such drive must be reformatted with an external nvme tool.
|
||||
You can check for support (reported as LBA format) by running the command
|
||||
"nvme id-ns -H <nvme device>" and then you can reformat to the selected profile
|
||||
(with complete data loss) with "nvme format -l <lbaf>.
|
||||
This way, you can also reformat NVMe drive to 4096-byte sectors,which is strongly recommended
|
||||
for encryption performance.
|
||||
|
||||
The required device mapper for inline mode was introduced in Linux kernel version 6.11.
|
||||
|
||||
The inline mode can be used with the new --integrity-inline option.
|
||||
|
||||
For integritysetup, the kernel dm-integrity layer is still used, but it directly maps metadata
|
||||
to the hardware (eliminating the journal).
|
||||
For cryptsetup, the dm-integrity layer is eliminated, and only the dm-crypt kernel driver is used.
|
||||
The libcryptsetup exports a new crypt_format_inline API call.
|
||||
|
||||
Examples (underlying device must provide inline HW metadata space):
|
||||
|
||||
Use integritysetup format with inline mode with default CRC32 checksums:
|
||||
|
||||
# integritysetup format --sector-size 4096 --integrity-inline <device> [--no-wipe]
|
||||
# integritysetup open <device> test
|
||||
# integritysetup status test
|
||||
/dev/mapper/test is active.
|
||||
type: INTEGRITY
|
||||
tag size: 4 [bytes]
|
||||
integrity: crc32c
|
||||
device: <device>
|
||||
sector size: 4096 [bytes]
|
||||
...
|
||||
inline mode
|
||||
journal: not active
|
||||
|
||||
Use LUKS2 with authenticated encryption (here with AEGIS AEAD cipher):
|
||||
|
||||
# cryptsetup luksFormat --integrity-inline --integrity aead --sector-size 4096 \
|
||||
-c aegis128-random --key-size 128 <device> [--integrity-no-wipe]
|
||||
# cryptsetup open <device> test
|
||||
# cryptsetup luksDump <device>
|
||||
...
|
||||
Requirements: inline-hw-tags
|
||||
|
||||
After format, the inline mode is used automatically, and no special options are needed.
|
||||
Please check the manual pages for more details about used options.
|
||||
|
||||
Note that the LUKS2 authenticated encryption is still an experimental feature.
|
||||
The inline mode only improves performance by removing the dm-integrity layer.
|
||||
|
||||
* Finalize use of keyslot context API.
|
||||
|
||||
Keyslot context is a generic abstraction over keyslot manipulation.
|
||||
It extends many exiting commands by additional functions like tokens in activation, resume,
|
||||
reencryption and similar commands without introducing new specific API functions.
|
||||
|
||||
* Make all keyslot context types fully self-contained.
|
||||
|
||||
In the previous version, the caller is responsible for releasing of some allocated memory.
|
||||
In this version, all memory is allocated internally. The existing keyslot context API function
|
||||
provides backward compatibility through versioned symbols.
|
||||
|
||||
* Add --key-description and --new-key-description cryptsetup options.
|
||||
|
||||
These can be used for the specification of the keyring with passphrase retrieval in the open,
|
||||
resize, luksResume, luksFormat, luksAddKey and luksDump.
|
||||
|
||||
* Support more precise keyslot selection in reencryption initialization.
|
||||
|
||||
Reencryption must update stored keys in keyslots, so it needs to unlock all keyslots first.
|
||||
|
||||
When no specific keyslot is selected by the --key-slot option, all active keyslots are updated.
|
||||
|
||||
Users may narrow down the selection of keyslots by specifying either --token-id, --token-type
|
||||
or --token-only option. Only keyslots associated with the specific token (--token-id) or
|
||||
a specific type (--token-type) or any token (--token-only) will be updated.
|
||||
All other keyslots will be erased after reencryption is finished.
|
||||
|
||||
During reencryption, there are two volume keys (old and new).
|
||||
For very specific use cases, reencryption can also be initialized by providing
|
||||
volume keys directly by --volume-key-file, --new-volume-key-file, --volume-key-keyring
|
||||
or --new-volume-key-keyring options. These options allow reencryption of the device with
|
||||
no active keyslots (these can be added later).
|
||||
If the --force-no-keyslots option is specified, all active keyslots will be erased after
|
||||
the reencryption operation is finished.
|
||||
|
||||
* Allow reencryption to resume using token and volume keys.
|
||||
|
||||
The reencryption can be resumed using tokens (similar to initialization described above).
|
||||
For very specific use cases, reencryption can be resumed by providing volume keys.
|
||||
|
||||
* Cryptsetup repair command now tries to check LUKS keyslot areas for corruption.
|
||||
|
||||
A keyslot binary area contains an encrypted volume key diffused to a larger area by
|
||||
the anti-forensic splitter. If this area is corrupted, the keyslot can no longer be unlocked,
|
||||
even with the correct password.
|
||||
|
||||
Active keyslot area should look like random data, so some specific corruption can be detected
|
||||
by randomness analysis.
|
||||
|
||||
Cryptsetup repair command now tries to analyze the area expecting a uniform distribution
|
||||
of bytes in 4096-byte blocks. If a problem is detected, it tries to localize corruption
|
||||
in a smaller block (using the expected bit count).
|
||||
Both tests are based on the Chi-squared statistical test.
|
||||
|
||||
This analysis can replace the external keyslot check program and usually is more sensitive.
|
||||
However, it cannot detect all corruptions and can produce false positives.
|
||||
|
||||
Please use it as a hint when your password is no longer accepted, and you suspect
|
||||
header corruption. This is the example output of the analysis:
|
||||
|
||||
# cryptsetup repair <device>
|
||||
Keyslot 2 binary data could be corrupted.
|
||||
Suspected offset: 0x88000
|
||||
You can use hexdump -v -C -n 128 -s <offset_0xXXXX> <device> to inspect the data.
|
||||
|
||||
The test does not modify the header. A keyslot corruption cannot be repaired.
|
||||
You have to use a backup header.
|
||||
|
||||
* Opal2 SED: PSID keyfile is now expected to be 32 alphanumeric characters.
|
||||
|
||||
If the keyfile size is not explicitly set, it uses only first 32 bytes.
|
||||
All Opal2 manufacturers seem to use PSID of this length.
|
||||
|
||||
* Opal2: Avoid the Erase method and use Secure Erase for locking range.
|
||||
|
||||
The Erase method is defined for Single-user mode (SUM) and works on SUM-enabled locking ranges.
|
||||
As we do not use SUM yet, this always fails and falls back to Secure erase anyway.
|
||||
|
||||
* Opal2: Fix some error description (in debug only).
|
||||
|
||||
Some Opal error messages were incorrect.
|
||||
Cryptsetup now use all codes according to TCG specifications.
|
||||
|
||||
* Opal2: Do not allow deferred deactivation.
|
||||
|
||||
The self-encrypting drive must be locked immediately; deferred deactivation is not supported.
|
||||
|
||||
* Allow --reduce-device-size and --device-size combination for reencryption (encrypt) action.
|
||||
|
||||
For some very specific cases, this can be used to encrypt only part of the device together
|
||||
with allocation a new space for the LUKS header.
|
||||
|
||||
* Fix the userspace storage backend to support kernel "capi:" cipher specification format.
|
||||
|
||||
This avoids unnecessary fallback to the device-mapper instead of the userspace crypto library
|
||||
in luksFormat. The "capi:" is Linux kernel cryptographic format.
|
||||
For example, capi:xts(aes)-plain64 is equivalent of aes-xts-plain64.
|
||||
|
||||
* Disallow conversion from LUKS2 to LUKS1 if kernel "capi:" cipher specification is used.
|
||||
|
||||
LUKS1 never officially supported this cipher specification format.
|
||||
Such devices cannot be converted to LUKS1 (while existing devices can still be activated).
|
||||
|
||||
* Explicitly disallow kernel "capi:" cipher specification format for LUKS2 keyslot encryption.
|
||||
|
||||
This specification is intended to be used for data encryption, not for keyslots.
|
||||
|
||||
* Do not allow conversion of LUKS2 to LUKS1 if an unbound keyslot is present.
|
||||
|
||||
LUKS1 does not support unbound keyslots. Such devices cannot be converted.
|
||||
|
||||
* cryptsetup: Adjust the XTS key size for kernel "capi:" cipher specification.
|
||||
|
||||
Double key size as there are two keys the same way as for dm-crypt format.
|
||||
|
||||
* Remove keyslot warning about possible failure due to low memory.
|
||||
|
||||
This check was intended to warn users about possible out-of-memory situations
|
||||
but produced many false positives.
|
||||
|
||||
* Do not limit Argon2 KDF memory cost on systems with more than 4GB of available memory.
|
||||
|
||||
The memory cost is intended to be limited only in low-memory situations (like virtual machines
|
||||
without swap), not on systems with plenty of RAM.
|
||||
|
||||
* Properly report out of memory error for cryptographic backends implementing Argon2.
|
||||
|
||||
* Avoid KDF2 memory cost overflow on 32-bit platforms.
|
||||
|
||||
* Do not use page size as a fallback for device block size.
|
||||
|
||||
This check produced wrong values if used on platforms with larger page sizes (64kB)
|
||||
and specific underlying storage (like ZFS).
|
||||
|
||||
* veritysetup: Check hash device size in advance.
|
||||
|
||||
If hashes are stored in a file image, allocate the size in advance.
|
||||
For a block device, check if hashes (Merkle tree) fits the device.
|
||||
|
||||
* Print a better error message for unsupported LUKS2 AEAD device resize.
|
||||
|
||||
* Optimize LUKS2 metadata writes.
|
||||
|
||||
LUKS2 supports several JSON area length configurations. Do not write full metadata
|
||||
(including padding), as it may generate noticeable overhead with LUKS2.
|
||||
|
||||
* veritysetup: support --error-as-corruption option.
|
||||
|
||||
The panic/restart_on_error options were introduced in Linux kernel 6.12 and process errors
|
||||
(like media read error) the same way as data corruption.
|
||||
Use this flag in combination with --panic-on-corruption or --restart-on-corruption.
|
||||
|
||||
* Report all sizes in status and dump command output in the correct units.
|
||||
|
||||
Since the support of --sector-size option, the meaning of "sectors" became ambiguous as it
|
||||
usually means 512-byte sectors (device-mapper unit). Confusion occurs when the sector size
|
||||
is 4096 bytes while units used for display are 512-byte sectors.
|
||||
|
||||
All status commands in tools now display units explicitly to avoid confusion.
|
||||
|
||||
For example:
|
||||
# cryptsetup status test
|
||||
...
|
||||
sector size: 4096 [bytes]
|
||||
offset: 32768 [512-byte units] (134217728 [bytes])
|
||||
size: 7501443760 [512-byte units] (30725913640960 [bytes])
|
||||
|
||||
If you parse the output of status commands, please check your scripts to ensure they work
|
||||
with the new output properly.
|
||||
|
||||
* Add --integrity-key-size option to cryptsetup.
|
||||
|
||||
This option can be used to set up non-standard integrity key size (e.g. for HMAC).
|
||||
It adds a new (optional) JSON "key_size" attribute in the segment.integrity JSON object
|
||||
(see updated LUKS2 specification). If not set, the code uses selected hash length size.
|
||||
|
||||
* Support trusted & encrypted keyrings for plain devices.
|
||||
|
||||
* Support plain format resize with a keyring key.
|
||||
|
||||
If a plain dm-crypt device references the keyring, cryptsetup now allows resizing.
|
||||
The user must ensure that the key in the keyring is unchanged since activation.
|
||||
Otherwise, reloading the key can cause data corruption after an unexpected key change.
|
||||
|
||||
* TCRYPT: Clear mapping of system-encrypted partitions.
|
||||
|
||||
TrueCrypt/VeraCrypt supports full system encryption (only a partition table is not encrypted)
|
||||
or system partition encryption (only a system partition is encrypted).
|
||||
The metadata header then contains the offset and size of the encrypted area.
|
||||
Cryptsetup needs to know the specific partition offset to calculate encryption parameters.
|
||||
|
||||
To properly map a partition, the user must specify a real partition device so cryptsetup
|
||||
can calculate this offset. As the partition can be an image in a file, cryptsetup now tries
|
||||
to determine proper parameters and use device size stored in VeraCrypt metadata.
|
||||
|
||||
Please see the manual page description (TCRYPT section) for a detailed description.
|
||||
|
||||
* TCRYPT: Print all information from the decrypted metadata header in the tcryptDump command.
|
||||
|
||||
Print also volume sizes (if present) and flags.
|
||||
|
||||
* Always lock the volume key structure in memory.
|
||||
|
||||
Some memory for safe allocation was not allocated from locked (unswappable) memory.
|
||||
Older cryptsetup locked all memory. Selective locking was introduced in version 2.6.0.
|
||||
|
||||
* Do not run direct-io read check on block devices.
|
||||
|
||||
Block devices always support direct-io.
|
||||
This check produced unnecessary error with locked Opal2 devices.
|
||||
|
||||
* Fix a possible segfault in deferred deactivation.
|
||||
|
||||
Thanks Clément Guérin for the report.
|
||||
|
||||
* Exclude cipher allocation time from the cryptsetup benchmark.
|
||||
|
||||
* Add Mbed-TLS optional crypto backend.
|
||||
|
||||
Mbed-TLS is a tiny TLS implementation designed for embedded environments.
|
||||
The backend can be enabled with the --with-crypto_backend=mbedtls configure option.
|
||||
|
||||
* Fix the wrong preprocessor use of #ifdef for config.h processed by Meson.
|
||||
|
||||
Cryptsetup supports Autoconf and, optionally, Meson configuration.
|
||||
Part of the code wrongly used #ifdef instead of #if conditional sections.
|
||||
This caused problems with Meson-generated config.h.
|
||||
|
||||
* Reorganize license files.
|
||||
|
||||
The license text files are now in docs/licenses.
|
||||
The COPYING file in the root directory is the default license.
|
||||
|
||||
Libcryptsetup API extensions
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
The libcryptsetup API is backward compatible with all existing symbols.
|
||||
|
||||
Due to the self-contained memory allocation, these symbols have the new version
|
||||
crypt_keyslot_context_init_by_passphrase;
|
||||
crypt_keyslot_context_init_by_keyfile;
|
||||
crypt_keyslot_context_init_by_token;
|
||||
crypt_keyslot_context_init_by_volume_key;
|
||||
crypt_keyslot_context_init_by_signed_key;
|
||||
crypt_keyslot_context_init_by_keyring;
|
||||
crypt_keyslot_context_init_by_vk_in_keyring;
|
||||
|
||||
New symbols:
|
||||
crypt_format_inline
|
||||
crypt_get_old_volume_key_size
|
||||
crypt_reencrypt_init_by_keyslot_context
|
||||
crypt_safe_memcpy
|
||||
|
||||
New defines:
|
||||
CRYPT_ACTIVATE_HIGH_PRIORITY
|
||||
CRYPT_ACTIVATE_ERROR_AS_CORRUPTION
|
||||
CRYPT_ACTIVATE_INLINE_MODE
|
||||
CRYPT_REENCRYPT_CREATE_NEW_DIGEST
|
||||
|
||||
New requirement flag:
|
||||
CRYPT_REQUIREMENT_INLINE_HW_TAGS
|
||||
40
docs/v2.8.1-ReleaseNotes
Normal file
40
docs/v2.8.1-ReleaseNotes
Normal file
@@ -0,0 +1,40 @@
|
||||
Cryptsetup 2.8.1 Release Notes
|
||||
==============================
|
||||
Stable bug-fix release with minor extensions.
|
||||
|
||||
All users of cryptsetup 2.8.0 must upgrade to this version.
|
||||
|
||||
Changes since version 2.8.0
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* Fix status and deactivation of TCRYPT (VeraCrypt compatible) devices that use chained ciphers.
|
||||
|
||||
* Fix unlocking BITLK (BitLocker compatible) devices with multibyte UTF8 characters in the passphrase.
|
||||
|
||||
* Do not allow activation of the LUKS2 device if the used keyslot is not encrypted (it uses a null cipher).
|
||||
|
||||
Such a configuration cannot be created by cryptsetup, but can be crafted outside of it.
|
||||
Null cipher is sometimes used to create an empty container for later reencryption.
|
||||
Only an empty passphrase can activate such a container (the same as in LUKS1).
|
||||
|
||||
* Do not silently decrease PBKDF parallel cost (threads) if set by an option.
|
||||
The maximum parallel cost is limited to 4 threads.
|
||||
|
||||
* Fixes to configuration and installation scripts.
|
||||
|
||||
Meson and autoconf tools now properly support --prefix option for temporary directory installation.
|
||||
Multiple fixes and cleanups to config.h for compatibility between Meson and autoconf.
|
||||
Fix the luks2-external-tokens-path Meson option to work the same as in autoconf.
|
||||
Fix Meson install for tool binaries, install fvault2Open man page and include test/fuzz/meson.build in release.
|
||||
|
||||
* Major update to manual pages.
|
||||
|
||||
Try to explain the PBKDF hardcoded limits.
|
||||
Add a better explanation for automatic integrity tag recalculation.
|
||||
Mention crypt/verity/integritytab.
|
||||
Remove or reformulate some misleading warnings present only with old and no longer supported kernels.
|
||||
Clarify that some commands do not wipe data and unify OPAL reset wording.
|
||||
Clarify the --label option.
|
||||
There are also many other grammar and stylistic fixes to unify the man-page style.
|
||||
|
||||
* Fixes for false-positive and annoying (optional) warnings added in recent compilers.
|
||||
@@ -1,23 +1,10 @@
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
/*
|
||||
* BITLK (BitLocker-compatible) volume handling
|
||||
*
|
||||
* Copyright (C) 2019-2023 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2019-2023 Milan Broz
|
||||
* Copyright (C) 2019-2023 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.
|
||||
* Copyright (C) 2019-2025 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2019-2025 Milan Broz
|
||||
* Copyright (C) 2019-2025 Vojtech Trefny
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
@@ -124,6 +111,7 @@ struct bitlk_superblock {
|
||||
struct bitlk_fve_metadata {
|
||||
/* FVE metadata block header */
|
||||
uint8_t signature[8];
|
||||
/* size of this block (in 16-byte units) */
|
||||
uint16_t fve_size;
|
||||
uint16_t fve_version;
|
||||
uint16_t curr_state;
|
||||
@@ -145,6 +133,32 @@ struct bitlk_fve_metadata {
|
||||
uint64_t creation_time;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct bitlk_validation_hash {
|
||||
uint16_t size;
|
||||
uint16_t role;
|
||||
uint16_t type;
|
||||
uint16_t flags;
|
||||
/* likely a hash type code, anything other than 0x2005 isn't supported */
|
||||
uint16_t hash_type;
|
||||
uint16_t unknown1;
|
||||
/* SHA-256 */
|
||||
uint8_t hash[32];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct bitlk_fve_metadata_validation {
|
||||
/* FVE metadata validation block header */
|
||||
uint16_t validation_size;
|
||||
uint16_t validation_version;
|
||||
uint32_t fve_crc32;
|
||||
/* this is a single nested structure's header defined here for simplicity */
|
||||
uint16_t nested_struct_size;
|
||||
uint16_t nested_struct_role;
|
||||
uint16_t nested_struct_type;
|
||||
uint16_t nested_struct_flags;
|
||||
/* datum containing a similar nested structure (encrypted using VMK) with hash (SHA256) */
|
||||
uint8_t nested_struct_data[BITLK_VALIDATION_VMK_DATA_SIZE];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct bitlk_entry_header_block {
|
||||
uint64_t offset;
|
||||
uint64_t size;
|
||||
@@ -250,10 +264,11 @@ static int parse_vmk_entry(struct crypt_device *cd, uint8_t *data, int start, in
|
||||
bool supported = false;
|
||||
int r = 0;
|
||||
|
||||
/* only passphrase or recovery passphrase vmks are supported (can be used to activate) */
|
||||
/* only passphrase, recovery passphrase, startup key and clearkey vmks are supported (can be used to activate) */
|
||||
supported = (*vmk)->protection == BITLK_PROTECTION_PASSPHRASE ||
|
||||
(*vmk)->protection == BITLK_PROTECTION_RECOVERY_PASSPHRASE ||
|
||||
(*vmk)->protection == BITLK_PROTECTION_STARTUP_KEY;
|
||||
(*vmk)->protection == BITLK_PROTECTION_STARTUP_KEY ||
|
||||
(*vmk)->protection == BITLK_PROTECTION_CLEAR_KEY;
|
||||
|
||||
while ((end - start) >= (ssize_t)(sizeof(key_entry_size) + sizeof(key_entry_type) + sizeof(key_entry_value))) {
|
||||
/* size of this entry */
|
||||
@@ -310,20 +325,19 @@ static int parse_vmk_entry(struct crypt_device *cd, uint8_t *data, int start, in
|
||||
crypt_volume_key_add_next(&((*vmk)->vk), vk);
|
||||
/* clear key for a partially decrypted volume */
|
||||
} else if (key_entry_value == BITLK_ENTRY_VALUE_KEY) {
|
||||
/* We currently don't want to support opening a partially decrypted
|
||||
* device so we don't need to store this key.
|
||||
*
|
||||
* key_size = key_entry_size - (BITLK_ENTRY_HEADER_LEN + 4);
|
||||
* key = (const char *) data + start + BITLK_ENTRY_HEADER_LEN + 4;
|
||||
* vk = crypt_alloc_volume_key(key_size, key);
|
||||
* if (vk == NULL)
|
||||
* return -ENOMEM;
|
||||
* crypt_volume_key_add_next(&((*vmk)->vk), vk);
|
||||
*/
|
||||
log_dbg(cd, "Skipping clear key metadata entry.");
|
||||
/* For clearkey protection, we need to store this key */
|
||||
key_size = key_entry_size - (BITLK_ENTRY_HEADER_LEN + 4);
|
||||
key = (const char *) data + start + BITLK_ENTRY_HEADER_LEN + 4;
|
||||
vk = crypt_alloc_volume_key(key_size, key);
|
||||
if (vk == NULL)
|
||||
return -ENOMEM;
|
||||
crypt_volume_key_add_next(&((*vmk)->vk), vk);
|
||||
/* unknown timestamps in recovery protected VMK */
|
||||
} else if (key_entry_value == BITLK_ENTRY_VALUE_RECOVERY_TIME) {
|
||||
;
|
||||
/* optional hint (?) string (masked email?), we can safely ignore it */
|
||||
} else if (key_entry_value == BITLK_ENTRY_VALUE_HINT) {
|
||||
;
|
||||
} else if (key_entry_value == BITLK_ENTRY_VALUE_STRING) {
|
||||
if (key_entry_size < BITLK_ENTRY_HEADER_LEN)
|
||||
return -EINVAL;
|
||||
@@ -353,6 +367,9 @@ static int parse_vmk_entry(struct crypt_device *cd, uint8_t *data, int start, in
|
||||
/* no idea what this is, lets hope it's not important */
|
||||
} else if (key_entry_value == BITLK_ENTRY_VALUE_USE_KEY && (*vmk)->protection == BITLK_PROTECTION_STARTUP_KEY) {
|
||||
;
|
||||
/* quietly ignore unsupported TPM key */
|
||||
} else if (key_entry_value == BITLK_ENTRY_VALUE_TPM_KEY && (*vmk)->protection == BITLK_PROTECTION_TPM) {
|
||||
;
|
||||
} else {
|
||||
if (supported) {
|
||||
log_err(cd, _("Unexpected metadata entry value '%u' found when parsing supported Volume Master Key."), key_entry_value);
|
||||
@@ -368,6 +385,54 @@ static int parse_vmk_entry(struct crypt_device *cd, uint8_t *data, int start, in
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool check_fve_metadata(struct bitlk_fve_metadata *fve)
|
||||
{
|
||||
if (memcmp(fve->signature, BITLK_SIGNATURE, sizeof(fve->signature)) || le16_to_cpu(fve->fve_version) != 2 ||
|
||||
(fve->fve_size << 4) > BITLK_FVE_METADATA_SIZE)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool check_fve_metadata_validation(struct bitlk_fve_metadata_validation *validation)
|
||||
{
|
||||
/* only check if there is room for CRC-32, the actual size must be larger */
|
||||
if (le16_to_cpu(validation->validation_size) < 8 || le16_to_cpu(validation->validation_version > 2))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool parse_fve_metadata_validation(struct bitlk_metadata *params, struct bitlk_fve_metadata_validation *validation)
|
||||
{
|
||||
/* extra checks for a nested structure (MAC) and BITLK FVE metadata */
|
||||
|
||||
if (le16_to_cpu(validation->validation_size) < sizeof(struct bitlk_fve_metadata_validation))
|
||||
return false;
|
||||
|
||||
if (le16_to_cpu(validation->nested_struct_size != BITLK_VALIDATION_VMK_HEADER_SIZE + BITLK_VALIDATION_VMK_DATA_SIZE) ||
|
||||
le16_to_cpu(validation->nested_struct_role) != 0 ||
|
||||
le16_to_cpu(validation->nested_struct_type) != 5)
|
||||
return false;
|
||||
|
||||
/* nonce */
|
||||
memcpy(params->validation->nonce,
|
||||
validation->nested_struct_data,
|
||||
BITLK_NONCE_SIZE);
|
||||
|
||||
/* MAC tag */
|
||||
memcpy(params->validation->mac_tag,
|
||||
validation->nested_struct_data + BITLK_NONCE_SIZE,
|
||||
BITLK_VMK_MAC_TAG_SIZE);
|
||||
|
||||
/* AES-CCM encrypted datum with SHA256 hash */
|
||||
memcpy(params->validation->enc_datum,
|
||||
validation->nested_struct_data + BITLK_NONCE_SIZE + BITLK_VMK_MAC_TAG_SIZE,
|
||||
BITLK_VALIDATION_VMK_DATA_SIZE - BITLK_NONCE_SIZE - BITLK_VMK_MAC_TAG_SIZE);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void BITLK_bitlk_fvek_free(struct bitlk_fvek *fvek)
|
||||
{
|
||||
if (!fvek)
|
||||
@@ -382,10 +447,8 @@ void BITLK_bitlk_vmk_free(struct bitlk_vmk *vmk)
|
||||
struct bitlk_vmk *vmk_next = NULL;
|
||||
|
||||
while (vmk) {
|
||||
if (vmk->guid)
|
||||
free(vmk->guid);
|
||||
if (vmk->name)
|
||||
free(vmk->name);
|
||||
free(vmk->guid);
|
||||
free(vmk->name);
|
||||
crypt_free_volume_key(vmk->vk);
|
||||
vmk_next = vmk->next;
|
||||
free(vmk);
|
||||
@@ -399,8 +462,8 @@ void BITLK_bitlk_metadata_free(struct bitlk_metadata *metadata)
|
||||
return;
|
||||
|
||||
free(metadata->guid);
|
||||
if (metadata->description)
|
||||
free(metadata->description);
|
||||
free(metadata->description);
|
||||
free(metadata->validation);
|
||||
BITLK_bitlk_vmk_free(metadata->vmks);
|
||||
BITLK_bitlk_fvek_free(metadata->fvek);
|
||||
}
|
||||
@@ -412,20 +475,25 @@ int BITLK_read_sb(struct crypt_device *cd, struct bitlk_metadata *params)
|
||||
struct bitlk_signature sig = {};
|
||||
struct bitlk_superblock sb = {};
|
||||
struct bitlk_fve_metadata fve = {};
|
||||
struct bitlk_fve_metadata_validation validation = {};
|
||||
struct bitlk_entry_vmk entry_vmk = {};
|
||||
uint8_t *fve_entries = NULL;
|
||||
uint8_t *fve_validated_block = NULL;
|
||||
size_t fve_entries_size = 0;
|
||||
uint32_t fve_metadata_size = 0;
|
||||
uint32_t fve_size_real = 0;
|
||||
int fve_offset = 0;
|
||||
char guid_buf[UUID_STR_LEN] = {0};
|
||||
uint16_t entry_size = 0;
|
||||
uint16_t entry_type = 0;
|
||||
int i = 0;
|
||||
int r = 0;
|
||||
int valid_fve_metadata_idx = -1;
|
||||
int start = 0;
|
||||
size_t key_size = 0;
|
||||
const char *key = NULL;
|
||||
char *description = NULL;
|
||||
struct crypt_hash *hash;
|
||||
|
||||
struct bitlk_vmk *vmk = NULL;
|
||||
struct bitlk_vmk *vmk_p = params->vmks;
|
||||
@@ -500,15 +568,80 @@ int BITLK_read_sb(struct crypt_device *cd, struct bitlk_metadata *params)
|
||||
for (i = 0; i < 3; i++)
|
||||
params->metadata_offset[i] = le64_to_cpu(sb.fve_offset[i]);
|
||||
|
||||
log_dbg(cd, "Reading BITLK FVE metadata of size %zu on device %s, offset %" PRIu64 ".",
|
||||
sizeof(fve), device_path(device), params->metadata_offset[0]);
|
||||
fve_validated_block = malloc(BITLK_FVE_METADATA_SIZE);
|
||||
if (fve_validated_block == NULL) {
|
||||
r = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* read FVE metadata from the first metadata area */
|
||||
if (read_lseek_blockwise(devfd, device_block_size(cd, device),
|
||||
device_alignment(device), &fve, sizeof(fve), params->metadata_offset[0]) != sizeof(fve) ||
|
||||
memcmp(fve.signature, BITLK_SIGNATURE, sizeof(fve.signature)) ||
|
||||
le16_to_cpu(fve.fve_version) != 2) {
|
||||
log_err(cd, _("Failed to read BITLK FVE metadata from %s."), device_path(device));
|
||||
for (i = 0; i < 3; i++) {
|
||||
/* iterate over FVE metadata copies and pick the valid one */
|
||||
log_dbg(cd, "Reading BITLK FVE metadata copy #%d of size %zu on device %s, offset %" PRIu64 ".",
|
||||
i, sizeof(fve), device_path(device), params->metadata_offset[i]);
|
||||
|
||||
if (read_lseek_blockwise(devfd, device_block_size(cd, device),
|
||||
device_alignment(device), &fve, sizeof(fve), params->metadata_offset[i]) != sizeof(fve) ||
|
||||
!check_fve_metadata(&fve) ||
|
||||
(fve_size_real = le16_to_cpu(fve.fve_size) << 4, read_lseek_blockwise(devfd, device_block_size(cd, device),
|
||||
device_alignment(device), &validation, sizeof(validation), params->metadata_offset[i] + fve_size_real) != sizeof(validation)) ||
|
||||
!check_fve_metadata_validation(&validation) ||
|
||||
/* double-fetch is here, but we aren't validating MAC */
|
||||
read_lseek_blockwise(devfd, device_block_size(cd, device), device_alignment(device), fve_validated_block, fve_size_real,
|
||||
params->metadata_offset[i]) != fve_size_real ||
|
||||
(crypt_crc32(~0, fve_validated_block, fve_size_real) ^ ~0) != le32_to_cpu(validation.fve_crc32)) {
|
||||
/* found an invalid FVE metadata copy, log and skip */
|
||||
log_dbg(cd, _("Failed to read or validate BITLK FVE metadata copy #%d from %s."), i, device_path(device));
|
||||
} else {
|
||||
/* found a valid FVE metadata copy, use it */
|
||||
valid_fve_metadata_idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (valid_fve_metadata_idx < 0) {
|
||||
/* all FVE metadata copies are invalid, fail */
|
||||
log_err(cd, _("Failed to read and validate BITLK FVE metadata from %s."), device_path(device));
|
||||
r = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* check that a valid FVE metadata block is in its expected location */
|
||||
if (params->metadata_offset[valid_fve_metadata_idx] != le64_to_cpu(fve.fve_offset[valid_fve_metadata_idx])) {
|
||||
log_err(cd, _("Failed to validate the location of BITLK FVE metadata from %s."), device_path(device));
|
||||
r = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* update offsets from a valid FVE metadata copy */
|
||||
for (i = 0; i < 3; i++)
|
||||
params->metadata_offset[i] = le64_to_cpu(fve.fve_offset[i]);
|
||||
|
||||
/* check that the FVE metadata hasn't changed between reads, because we are preparing for the MAC check */
|
||||
if (memcmp(&fve, fve_validated_block, sizeof(fve)) != 0) {
|
||||
log_err(cd, _("BITLK FVE metadata changed between reads from %s."), device_path(device));
|
||||
r = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
crypt_backend_memzero(¶ms->sha256_fve, 32);
|
||||
if (crypt_hash_init(&hash, "sha256")) {
|
||||
log_err(cd, _("Failed to hash BITLK FVE metadata read from %s."), device_path(device));
|
||||
r = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
crypt_hash_write(hash, (const char *)fve_validated_block, fve_size_real);
|
||||
crypt_hash_final(hash, (char *)¶ms->sha256_fve, 32);
|
||||
crypt_hash_destroy(hash);
|
||||
|
||||
/* do some extended checks against FVE metadata, but not including MAC verification */
|
||||
params->validation = malloc(sizeof(struct bitlk_validation));
|
||||
if (!params->validation) {
|
||||
r = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!parse_fve_metadata_validation(params, &validation)) {
|
||||
log_err(cd, _("Failed to parse BITLK FVE validation metadata from %s."), device_path(device));
|
||||
r = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
@@ -593,17 +726,18 @@ int BITLK_read_sb(struct crypt_device *cd, struct bitlk_metadata *params)
|
||||
}
|
||||
memset(fve_entries, 0, fve_entries_size);
|
||||
|
||||
log_dbg(cd, "Reading BITLK FVE metadata entries of size %zu on device %s, offset %" PRIu64 ".",
|
||||
fve_entries_size, device_path(device), params->metadata_offset[0] + BITLK_FVE_METADATA_HEADERS_LEN);
|
||||
log_dbg(cd, "Getting BITLK FVE metadata entries of size %zu on device %s, offset %" PRIu64 ".",
|
||||
fve_entries_size, device_path(device), params->metadata_offset[valid_fve_metadata_idx] + BITLK_FVE_METADATA_HEADERS_LEN);
|
||||
|
||||
if (read_lseek_blockwise(devfd, device_block_size(cd, device),
|
||||
device_alignment(device), fve_entries, fve_entries_size,
|
||||
params->metadata_offset[0] + BITLK_FVE_METADATA_HEADERS_LEN) != (ssize_t)fve_entries_size) {
|
||||
log_err(cd, _("Failed to read BITLK metadata entries from %s."), device_path(device));
|
||||
if (BITLK_FVE_METADATA_HEADERS_LEN + fve_entries_size > fve_size_real) {
|
||||
log_err(cd, _("Failed to check BITLK metadata entries previously read from %s."), device_path(device));
|
||||
r = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* fetch these entries from validated buffer to avoid double-fetch */
|
||||
memcpy(fve_entries, fve_validated_block + BITLK_FVE_METADATA_HEADERS_LEN, fve_entries_size);
|
||||
|
||||
while ((fve_entries_size - start) >= (sizeof(entry_size) + sizeof(entry_type))) {
|
||||
|
||||
/* size of this entry */
|
||||
@@ -724,10 +858,10 @@ int BITLK_read_sb(struct crypt_device *cd, struct bitlk_metadata *params)
|
||||
|
||||
start += entry_size;
|
||||
}
|
||||
|
||||
out:
|
||||
if (fve_entries)
|
||||
free(fve_entries);
|
||||
free(fve_entries);
|
||||
free(fve_validated_block);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -749,7 +883,7 @@ int BITLK_dump(struct crypt_device *cd, struct device *device, struct bitlk_meta
|
||||
log_std(cd, "Description: \t%s\n", params->description);
|
||||
log_std(cd, "Cipher name: \t%s\n", params->cipher);
|
||||
log_std(cd, "Cipher mode: \t%s\n", params->cipher_mode);
|
||||
log_std(cd, "Cipher key: \t%u bits\n", params->key_size);
|
||||
log_std(cd, "Cipher key: \t%u [bits]\n", params->key_size);
|
||||
|
||||
log_std(cd, "\n");
|
||||
|
||||
@@ -768,15 +902,15 @@ int BITLK_dump(struct crypt_device *cd, struct device *device, struct bitlk_meta
|
||||
|
||||
vk_p = vmk_p->vk;
|
||||
while (vk_p) {
|
||||
log_std(cd, "\tKey data size:\t%zu [bytes]\n", vk_p->keylength);
|
||||
vk_p = vk_p->next;
|
||||
log_std(cd, "\tKey data size:\t%zu [bytes]\n", crypt_volume_key_length(vk_p));
|
||||
vk_p = crypt_volume_key_next(vk_p);
|
||||
}
|
||||
vmk_p = vmk_p->next;
|
||||
next_id++;
|
||||
}
|
||||
|
||||
log_std(cd, " %d: FVEK\n", next_id);
|
||||
log_std(cd, "\tKey data size:\t%zu [bytes]\n", params->fvek->vk->keylength);
|
||||
log_std(cd, "\tKey data size:\t%zu [bytes]\n", crypt_volume_key_length(params->fvek->vk));
|
||||
|
||||
log_std(cd, "\n");
|
||||
|
||||
@@ -994,9 +1128,13 @@ static int bitlk_kdf(const char *password,
|
||||
struct crypt_hash *hd = NULL;
|
||||
int len = 0;
|
||||
char16_t *utf16Password = NULL;
|
||||
size_t utf16Len = 0;
|
||||
int i = 0;
|
||||
int r = 0;
|
||||
|
||||
if (!password)
|
||||
return -EINVAL;
|
||||
|
||||
memcpy(kdf.salt, salt, 16);
|
||||
|
||||
r = crypt_hash_init(&hd, BITLK_KDF_HASH);
|
||||
@@ -1019,7 +1157,8 @@ static int bitlk_kdf(const char *password,
|
||||
if (r < 0)
|
||||
goto out;
|
||||
|
||||
crypt_hash_write(hd, (char*)utf16Password, passwordLen * 2);
|
||||
utf16Len = crypt_char16_strlen(utf16Password);
|
||||
crypt_hash_write(hd, (char*)utf16Password, utf16Len * 2);
|
||||
r = crypt_hash_final(hd, kdf.initial_sha256, len);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
@@ -1065,11 +1204,14 @@ static int decrypt_key(struct crypt_device *cd,
|
||||
int r;
|
||||
uint16_t key_size = 0;
|
||||
|
||||
outbuf = crypt_safe_alloc(enc_key->keylength);
|
||||
outbuf = crypt_safe_alloc(crypt_volume_key_length(enc_key));
|
||||
if (!outbuf)
|
||||
return -ENOMEM;
|
||||
|
||||
r = crypt_bitlk_decrypt_key(key->key, key->keylength, enc_key->key, outbuf, enc_key->keylength,
|
||||
r = crypt_bitlk_decrypt_key(crypt_volume_key_get_key(key),
|
||||
crypt_volume_key_length(key),
|
||||
crypt_volume_key_get_key(enc_key), outbuf,
|
||||
crypt_volume_key_length(enc_key),
|
||||
(const char*)iv, iv_size, (const char*)tag, tag_size);
|
||||
if (r < 0) {
|
||||
if (r == -ENOTSUP)
|
||||
@@ -1080,9 +1222,10 @@ static int decrypt_key(struct crypt_device *cd,
|
||||
/* key_data has it's size as part of the metadata */
|
||||
memcpy(&key_size, outbuf, 2);
|
||||
key_size = le16_to_cpu(key_size);
|
||||
if (enc_key->keylength != key_size) {
|
||||
if (crypt_volume_key_length(enc_key) != key_size) {
|
||||
log_err(cd, _("Unexpected key data size."));
|
||||
log_dbg(cd, "Expected key data size: %zu, got %" PRIu16 "", enc_key->keylength, key_size);
|
||||
log_dbg(cd, "Expected key data size: %zu, got %" PRIu16 "",
|
||||
crypt_volume_key_length(enc_key), key_size);
|
||||
|
||||
r = -EINVAL;
|
||||
goto out;
|
||||
@@ -1092,7 +1235,7 @@ static int decrypt_key(struct crypt_device *cd,
|
||||
crypt_get_volume_key_size(cd) == 32) {
|
||||
/* 128bit AES-CBC with Elephant -- key size is 256 bit (2 keys) but key data is 512 bits,
|
||||
data: 16B CBC key, 16B empty, 16B elephant key, 16B empty */
|
||||
memcpy(outbuf + 16 + BITLK_OPEN_KEY_METADATA_LEN,
|
||||
crypt_safe_memcpy(outbuf + 16 + BITLK_OPEN_KEY_METADATA_LEN,
|
||||
outbuf + 2 * 16 + BITLK_OPEN_KEY_METADATA_LEN, 16);
|
||||
key_size = 32 + BITLK_OPEN_KEY_METADATA_LEN;
|
||||
}
|
||||
@@ -1106,6 +1249,41 @@ out:
|
||||
return r;
|
||||
}
|
||||
|
||||
static int get_clear_key(struct crypt_device *cd, const struct bitlk_vmk *vmk, struct volume_key **vmk_dec_key)
|
||||
{
|
||||
struct volume_key *nested_key = vmk->vk;
|
||||
|
||||
if (!nested_key) {
|
||||
log_dbg(cd, "Clearkey VMK structure incomplete - missing nested key");
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
struct volume_key *encrypted_vmk = crypt_volume_key_next(nested_key);
|
||||
|
||||
if (!encrypted_vmk) {
|
||||
log_dbg(cd, "Clearkey VMK structure incomplete - missing encrypted VMK");
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
/**
|
||||
* For clearkey protection, we need to decrypt the encrypted VMK using the nested key
|
||||
* and return the decrypted VMK as vmk_dec_key
|
||||
*/
|
||||
struct volume_key *decrypted_vmk = NULL;
|
||||
int r = decrypt_key(cd, &decrypted_vmk, encrypted_vmk, nested_key,
|
||||
vmk->mac_tag, BITLK_VMK_MAC_TAG_SIZE,
|
||||
vmk->nonce, BITLK_NONCE_SIZE, false);
|
||||
|
||||
if (r == 0 && decrypted_vmk) {
|
||||
log_dbg(cd, "Successfully decrypted VMK using nested key");
|
||||
*vmk_dec_key = decrypted_vmk;
|
||||
return 0;
|
||||
} else {
|
||||
log_dbg(cd, "Failed to decrypt VMK using nested key (error: %d)", r);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
int BITLK_get_volume_key(struct crypt_device *cd,
|
||||
const char *password,
|
||||
size_t passwordLen,
|
||||
@@ -1116,10 +1294,12 @@ int BITLK_get_volume_key(struct crypt_device *cd,
|
||||
struct volume_key *open_vmk_key = NULL;
|
||||
struct volume_key *vmk_dec_key = NULL;
|
||||
struct volume_key *recovery_key = NULL;
|
||||
struct bitlk_validation_hash dec_hash = {};
|
||||
const struct bitlk_vmk *next_vmk = NULL;
|
||||
|
||||
next_vmk = params->vmks;
|
||||
while (next_vmk) {
|
||||
bool is_decrypted = false;
|
||||
if (next_vmk->protection == BITLK_PROTECTION_PASSPHRASE) {
|
||||
r = bitlk_kdf(password, passwordLen, false, next_vmk->salt, &vmk_dec_key);
|
||||
if (r) {
|
||||
@@ -1141,7 +1321,8 @@ int BITLK_get_volume_key(struct crypt_device *cd,
|
||||
continue;
|
||||
}
|
||||
log_dbg(cd, "Trying to use given password as a recovery key.");
|
||||
r = bitlk_kdf(recovery_key->key, recovery_key->keylength,
|
||||
r = bitlk_kdf(crypt_volume_key_get_key(recovery_key),
|
||||
crypt_volume_key_length(recovery_key),
|
||||
true, next_vmk->salt, &vmk_dec_key);
|
||||
crypt_free_volume_key(recovery_key);
|
||||
if (r)
|
||||
@@ -1153,8 +1334,18 @@ int BITLK_get_volume_key(struct crypt_device *cd,
|
||||
continue;
|
||||
}
|
||||
log_dbg(cd, "Trying to use external key found in provided password.");
|
||||
} else if (next_vmk->protection == BITLK_PROTECTION_CLEAR_KEY) {
|
||||
r = get_clear_key(cd, next_vmk, &vmk_dec_key);
|
||||
if (r) {
|
||||
/* something wrong happened, but we still want to check other key slots */
|
||||
next_vmk = next_vmk->next;
|
||||
continue;
|
||||
}
|
||||
is_decrypted = true;
|
||||
open_vmk_key = vmk_dec_key;
|
||||
log_dbg(cd, "Extracted VMK using clearkey.");
|
||||
} else {
|
||||
/* only passphrase, recovery passphrase and startup key VMKs supported right now */
|
||||
/* only passphrase, recovery passphrase, startup key and clearkey VMKs supported right now */
|
||||
log_dbg(cd, "Skipping %s", get_vmk_protection_string(next_vmk->protection));
|
||||
next_vmk = next_vmk->next;
|
||||
if (r == 0)
|
||||
@@ -1163,19 +1354,51 @@ int BITLK_get_volume_key(struct crypt_device *cd,
|
||||
continue;
|
||||
}
|
||||
|
||||
log_dbg(cd, "Trying to decrypt %s.", get_vmk_protection_string(next_vmk->protection));
|
||||
r = decrypt_key(cd, &open_vmk_key, next_vmk->vk, vmk_dec_key,
|
||||
next_vmk->mac_tag, BITLK_VMK_MAC_TAG_SIZE,
|
||||
next_vmk->nonce, BITLK_NONCE_SIZE, false);
|
||||
if (!is_decrypted) {
|
||||
r = decrypt_key(cd, &open_vmk_key, next_vmk->vk, vmk_dec_key,
|
||||
next_vmk->mac_tag, BITLK_VMK_MAC_TAG_SIZE,
|
||||
next_vmk->nonce, BITLK_NONCE_SIZE, false);
|
||||
|
||||
crypt_free_volume_key(vmk_dec_key);
|
||||
}
|
||||
if (r < 0) {
|
||||
log_dbg(cd, "Failed to decrypt VMK using provided passphrase.");
|
||||
crypt_free_volume_key(vmk_dec_key);
|
||||
|
||||
if (r == -ENOTSUP)
|
||||
return r;
|
||||
next_vmk = next_vmk->next;
|
||||
continue;
|
||||
}
|
||||
crypt_free_volume_key(vmk_dec_key);
|
||||
|
||||
log_dbg(cd, "Trying to decrypt validation metadata using VMK.");
|
||||
r = crypt_bitlk_decrypt_key(crypt_volume_key_get_key(open_vmk_key),
|
||||
crypt_volume_key_length(open_vmk_key),
|
||||
(const char*)params->validation->enc_datum,
|
||||
(char *)&dec_hash,
|
||||
BITLK_VALIDATION_VMK_DATA_SIZE - BITLK_NONCE_SIZE - BITLK_VMK_MAC_TAG_SIZE,
|
||||
(const char*)params->validation->nonce, BITLK_NONCE_SIZE,
|
||||
(const char*)params->validation->mac_tag, BITLK_VMK_MAC_TAG_SIZE);
|
||||
if (r < 0) {
|
||||
log_dbg(cd, "Failed to decrypt validation metadata using VMK.");
|
||||
crypt_free_volume_key(open_vmk_key);
|
||||
if (r == -ENOTSUP)
|
||||
return r;
|
||||
break;
|
||||
}
|
||||
|
||||
/* now, do the MAC validation */
|
||||
if (le16_to_cpu(dec_hash.role) != 0 ||le16_to_cpu(dec_hash.type) != 1 ||
|
||||
(le16_to_cpu(dec_hash.hash_type) != 0x2005)) {
|
||||
log_dbg(cd, "Failed to parse decrypted validation metadata.");
|
||||
crypt_free_volume_key(open_vmk_key);
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
if (memcmp(dec_hash.hash, params->sha256_fve, sizeof(dec_hash.hash)) != 0) {
|
||||
log_dbg(cd, "Failed MAC validation of BITLK FVE metadata.");
|
||||
crypt_free_volume_key(open_vmk_key);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
r = decrypt_key(cd, open_fvek_key, params->fvek->vk, open_vmk_key,
|
||||
params->fvek->mac_tag, BITLK_VMK_MAC_TAG_SIZE,
|
||||
@@ -1204,8 +1427,6 @@ int BITLK_get_volume_key(struct crypt_device *cd,
|
||||
static int _activate_check(struct crypt_device *cd,
|
||||
const struct bitlk_metadata *params)
|
||||
{
|
||||
const struct bitlk_vmk *next_vmk = NULL;
|
||||
|
||||
if (!params->state) {
|
||||
log_err(cd, _("This BITLK device is in an unsupported state and cannot be activated."));
|
||||
return -ENOTSUP;
|
||||
@@ -1216,15 +1437,6 @@ static int _activate_check(struct crypt_device *cd,
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
next_vmk = params->vmks;
|
||||
while (next_vmk) {
|
||||
if (next_vmk->protection == BITLK_PROTECTION_CLEAR_KEY) {
|
||||
log_err(cd, _("Activation of partially decrypted BITLK device is not supported."));
|
||||
return -ENOTSUP;
|
||||
}
|
||||
next_vmk = next_vmk->next;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1248,7 +1460,7 @@ static int _activate(struct crypt_device *cd,
|
||||
uint64_t next_start = 0;
|
||||
uint64_t next_end = 0;
|
||||
uint64_t last_segment = 0;
|
||||
uint32_t dmt_flags = 0;
|
||||
uint64_t dmt_flags = 0;
|
||||
|
||||
r = _activate_check(cd, params);
|
||||
if (r)
|
||||
@@ -1372,7 +1584,7 @@ static int _activate(struct crypt_device *cd,
|
||||
crypt_get_cipher_spec(cd),
|
||||
segments[i].iv_offset,
|
||||
segments[i].iv_offset,
|
||||
NULL, 0,
|
||||
NULL, 0, 0,
|
||||
params->sector_size);
|
||||
if (r)
|
||||
goto out;
|
||||
@@ -1408,54 +1620,17 @@ out:
|
||||
return r;
|
||||
}
|
||||
|
||||
int BITLK_activate_by_passphrase(struct crypt_device *cd,
|
||||
const char *name,
|
||||
const char *password,
|
||||
size_t passwordLen,
|
||||
const struct bitlk_metadata *params,
|
||||
uint32_t flags)
|
||||
{
|
||||
int r = 0;
|
||||
struct volume_key *open_fvek_key = NULL;
|
||||
|
||||
r = _activate_check(cd, params);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = BITLK_get_volume_key(cd, password, passwordLen, params, &open_fvek_key);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
|
||||
/* Password verify only */
|
||||
if (!name)
|
||||
goto out;
|
||||
|
||||
r = _activate(cd, name, open_fvek_key, params, flags);
|
||||
out:
|
||||
crypt_free_volume_key(open_fvek_key);
|
||||
return r;
|
||||
}
|
||||
|
||||
int BITLK_activate_by_volume_key(struct crypt_device *cd,
|
||||
const char *name,
|
||||
const char *volume_key,
|
||||
size_t volume_key_size,
|
||||
struct volume_key *vk,
|
||||
const struct bitlk_metadata *params,
|
||||
uint32_t flags)
|
||||
{
|
||||
int r = 0;
|
||||
struct volume_key *open_fvek_key = NULL;
|
||||
int r;
|
||||
|
||||
r = _activate_check(cd, params);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
open_fvek_key = crypt_alloc_volume_key(volume_key_size, volume_key);
|
||||
if (!open_fvek_key)
|
||||
return -ENOMEM;
|
||||
|
||||
r = _activate(cd, name, open_fvek_key, params, flags);
|
||||
|
||||
crypt_free_volume_key(open_fvek_key);
|
||||
return r;
|
||||
return _activate(cd, name, vk, params, flags);
|
||||
}
|
||||
|
||||
@@ -1,23 +1,10 @@
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
/*
|
||||
* BITLK (BitLocker-compatible) header definition
|
||||
*
|
||||
* Copyright (C) 2019-2023 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2019-2023 Milan Broz
|
||||
* Copyright (C) 2019-2023 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.
|
||||
* Copyright (C) 2019-2025 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2019-2025 Milan Broz
|
||||
* Copyright (C) 2019-2025 Vojtech Trefny
|
||||
*/
|
||||
|
||||
#ifndef _CRYPTSETUP_BITLK_H
|
||||
@@ -34,6 +21,8 @@ struct volume_key;
|
||||
#define BITLK_NONCE_SIZE 12
|
||||
#define BITLK_SALT_SIZE 16
|
||||
#define BITLK_VMK_MAC_TAG_SIZE 16
|
||||
#define BITLK_VALIDATION_VMK_HEADER_SIZE 8
|
||||
#define BITLK_VALIDATION_VMK_DATA_SIZE 72
|
||||
|
||||
#define BITLK_STATE_NORMAL 0x0004
|
||||
|
||||
@@ -78,6 +67,7 @@ typedef enum {
|
||||
BITLK_ENTRY_VALUE_OFFSET_SIZE = 0x000f,
|
||||
BITLK_ENTRY_VALUE_RECOVERY_TIME = 0x015,
|
||||
BITLK_ENTRY_VALUE_GUID = 0x0017,
|
||||
BITLK_ENTRY_VALUE_HINT = 0x0018,
|
||||
} BITLKFVEEntryValue;
|
||||
|
||||
struct bitlk_vmk {
|
||||
@@ -97,6 +87,13 @@ struct bitlk_fvek {
|
||||
struct volume_key *vk;
|
||||
};
|
||||
|
||||
struct bitlk_validation {
|
||||
uint8_t mac_tag[BITLK_VMK_MAC_TAG_SIZE];
|
||||
uint8_t nonce[BITLK_NONCE_SIZE];
|
||||
/* technically, this is not "VMK", but some sources call it this way */
|
||||
uint8_t enc_datum[BITLK_VALIDATION_VMK_DATA_SIZE];
|
||||
};
|
||||
|
||||
struct bitlk_metadata {
|
||||
uint16_t sector_size;
|
||||
uint64_t volume_size;
|
||||
@@ -113,8 +110,10 @@ struct bitlk_metadata {
|
||||
uint32_t metadata_version;
|
||||
uint64_t volume_header_offset;
|
||||
uint64_t volume_header_size;
|
||||
const char *sha256_fve[32];
|
||||
struct bitlk_vmk *vmks;
|
||||
struct bitlk_fvek *fvek;
|
||||
struct bitlk_validation *validation;
|
||||
};
|
||||
|
||||
int BITLK_read_sb(struct crypt_device *cd, struct bitlk_metadata *params);
|
||||
@@ -127,17 +126,9 @@ int BITLK_get_volume_key(struct crypt_device *cd,
|
||||
const struct bitlk_metadata *params,
|
||||
struct volume_key **open_fvek_key);
|
||||
|
||||
int BITLK_activate_by_passphrase(struct crypt_device *cd,
|
||||
const char *name,
|
||||
const char *password,
|
||||
size_t passwordLen,
|
||||
const struct bitlk_metadata *params,
|
||||
uint32_t flags);
|
||||
|
||||
int BITLK_activate_by_volume_key(struct crypt_device *cd,
|
||||
const char *name,
|
||||
const char *volume_key,
|
||||
size_t volume_key_size,
|
||||
struct volume_key *vk,
|
||||
const struct bitlk_metadata *params,
|
||||
uint32_t flags);
|
||||
|
||||
|
||||
@@ -10,13 +10,13 @@
|
||||
#include <stdint.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
#if defined(HAVE_BYTESWAP_H)
|
||||
#if HAVE_BYTESWAP_H
|
||||
# include <byteswap.h>
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_ENDIAN_H)
|
||||
#if HAVE_ENDIAN_H
|
||||
# include <endian.h>
|
||||
#elif defined(HAVE_SYS_ENDIAN_H) /* BSDs have them here */
|
||||
#elif HAVE_SYS_ENDIAN_H /* BSDs have them here */
|
||||
# include <sys/endian.h>
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,23 +1,10 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* cryptsetup plain device helper functions
|
||||
*
|
||||
* Copyright (C) 2004 Jana Saout <jana@saout.de>
|
||||
* Copyright (C) 2010-2023 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2023 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* Copyright (C) 2010-2025 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2025 Milan Broz
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
@@ -105,7 +92,7 @@ int crypt_plain_hash(struct crypt_device *cd,
|
||||
log_dbg(cd, "Too short plain passphrase.");
|
||||
return -EINVAL;
|
||||
}
|
||||
memcpy(key, passphrase, hash_size);
|
||||
crypt_safe_memcpy(key, passphrase, hash_size);
|
||||
r = 0;
|
||||
} else
|
||||
r = hash(hash_name_buf, hash_size, key, passphrase_size, passphrase);
|
||||
|
||||
@@ -13,7 +13,8 @@ libcrypto_backend_la_SOURCES = \
|
||||
lib/crypto_backend/utf8.c \
|
||||
lib/crypto_backend/argon2_generic.c \
|
||||
lib/crypto_backend/cipher_generic.c \
|
||||
lib/crypto_backend/cipher_check.c
|
||||
lib/crypto_backend/cipher_check.c \
|
||||
lib/crypto_backend/memutils.c
|
||||
|
||||
if CRYPTO_BACKEND_GCRYPT
|
||||
libcrypto_backend_la_SOURCES += lib/crypto_backend/crypto_gcrypt.c
|
||||
@@ -30,6 +31,9 @@ endif
|
||||
if CRYPTO_BACKEND_NETTLE
|
||||
libcrypto_backend_la_SOURCES += lib/crypto_backend/crypto_nettle.c
|
||||
endif
|
||||
if CRYPTO_BACKEND_MBEDTLS
|
||||
libcrypto_backend_la_SOURCES += lib/crypto_backend/crypto_mbedtls.c
|
||||
endif
|
||||
|
||||
if CRYPTO_INTERNAL_PBKDF2
|
||||
libcrypto_backend_la_SOURCES += lib/crypto_backend/pbkdf2_generic.c
|
||||
|
||||
@@ -360,7 +360,7 @@ int blake2b_long(void *pout, size_t outlen, const void *in, size_t inlen) {
|
||||
TRY(blake2b_final(&blake_state, out, outlen));
|
||||
} else {
|
||||
uint32_t toproduce;
|
||||
uint8_t out_buffer[BLAKE2B_OUTBYTES];
|
||||
uint8_t out_buffer[BLAKE2B_OUTBYTES] = {0};
|
||||
uint8_t in_buffer[BLAKE2B_OUTBYTES];
|
||||
TRY(blake2b_init(&blake_state, BLAKE2B_OUTBYTES));
|
||||
TRY(blake2b_update(&blake_state, outlen_bytes, sizeof(outlen_bytes)));
|
||||
|
||||
@@ -128,7 +128,7 @@ void secure_wipe_memory(void *v, size_t n) {
|
||||
void secure_wipe_memory(void *v, size_t n) {
|
||||
memset_s(v, n, 0, n);
|
||||
}
|
||||
#elif defined(HAVE_EXPLICIT_BZERO)
|
||||
#elif HAVE_EXPLICIT_BZERO
|
||||
void secure_wipe_memory(void *v, size_t n) {
|
||||
explicit_bzero(v, n);
|
||||
}
|
||||
@@ -356,12 +356,9 @@ static int fill_memory_blocks_mt(argon2_instance_t *instance) {
|
||||
}
|
||||
|
||||
fail:
|
||||
if (thread != NULL) {
|
||||
free(thread);
|
||||
}
|
||||
if (thr_data != NULL) {
|
||||
free(thr_data);
|
||||
}
|
||||
free(thread);
|
||||
free(thr_data);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
@@ -83,7 +83,7 @@
|
||||
static int b64_byte_to_char(unsigned x) {
|
||||
return (LT(x, 26) & (x + 'A')) |
|
||||
(GE(x, 26) & LT(x, 52) & (x + ('a' - 26))) |
|
||||
(GE(x, 52) & LT(x, 62) & (x + ('0' - 52))) | (EQ(x, 62) & '+') |
|
||||
(GE(x, 52) & LT(x, 62) & (x - (52 - '0'))) | (EQ(x, 62) & '+') |
|
||||
(EQ(x, 63) & '/');
|
||||
}
|
||||
|
||||
|
||||
@@ -1,35 +1,25 @@
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
/*
|
||||
* Argon2 PBKDF2 library wrapper
|
||||
*
|
||||
* Copyright (C) 2016-2023 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2016-2023 Milan Broz
|
||||
*
|
||||
* 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.
|
||||
* Copyright (C) 2016-2025 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2016-2025 Milan Broz
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include "crypto_backend_internal.h"
|
||||
|
||||
/* Check for HAVE_ARGON2_H is run only if libargon2 code is used */
|
||||
#if USE_INTERNAL_ARGON2 || HAVE_ARGON2_H
|
||||
|
||||
#define CONST_CAST(x) (x)(uintptr_t)
|
||||
|
||||
#if HAVE_ARGON2_H
|
||||
#include <argon2.h>
|
||||
#else
|
||||
#include "argon2/argon2.h"
|
||||
#endif
|
||||
|
||||
#define CONST_CAST(x) (x)(uintptr_t)
|
||||
|
||||
#if USE_INTERNAL_ARGON2 || HAVE_ARGON2_H
|
||||
int argon2(const char *type, const char *password, size_t password_length,
|
||||
const char *salt, size_t salt_length,
|
||||
char *key, size_t key_length,
|
||||
@@ -52,6 +42,9 @@ int argon2(const char *type, const char *password, size_t password_length,
|
||||
};
|
||||
int r;
|
||||
|
||||
/* This code must not be run if crypt backend library natively supports Argon2 */
|
||||
assert(!(crypt_backend_flags() & CRYPT_BACKEND_ARGON2));
|
||||
|
||||
if (!strcmp(type, "argon2i"))
|
||||
atype = Argon2_i;
|
||||
else if(!strcmp(type, "argon2id"))
|
||||
@@ -87,3 +80,19 @@ int argon2(const char *type, const char *password, size_t password_length,
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* Additional string for crypt backend version */
|
||||
const char *crypt_argon2_version(void)
|
||||
{
|
||||
const char *version = "";
|
||||
|
||||
if (crypt_backend_flags() & CRYPT_BACKEND_ARGON2)
|
||||
return version;
|
||||
|
||||
#if HAVE_ARGON2_H /* this has priority over internal argon2 */
|
||||
version = " [external libargon2]";
|
||||
#elif USE_INTERNAL_ARGON2
|
||||
version = " [cryptsetup libargon2]";
|
||||
#endif
|
||||
return version;
|
||||
}
|
||||
|
||||
@@ -1,24 +1,11 @@
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
/*
|
||||
* Base64 "Not encryption" helpers, copied and adapted from systemd project.
|
||||
*
|
||||
* Copyright (C) 2010 Lennart Poettering
|
||||
*
|
||||
* cryptsetup related changes
|
||||
* Copyright (C) 2021-2023 Milan Broz
|
||||
*
|
||||
* 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.
|
||||
* Copyright (C) 2021-2025 Milan Broz
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
@@ -32,7 +19,7 @@
|
||||
/* https://tools.ietf.org/html/rfc4648#section-4 */
|
||||
static char base64char(int x)
|
||||
{
|
||||
static const char table[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
static const char table[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"abcdefghijklmnopqrstuvwxyz"
|
||||
"0123456789+/";
|
||||
return table[x & 63];
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
/*
|
||||
* Cipher performance check
|
||||
*
|
||||
* Copyright (C) 2018-2023 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2018-2023 Milan Broz
|
||||
*
|
||||
* 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.
|
||||
* Copyright (C) 2018-2025 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2018-2025 Milan Broz
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
@@ -55,43 +42,36 @@ static int time_ms(struct timespec *start, struct timespec *end, double *ms)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cipher_perf_one(const char *name, const char *mode, char *buffer, size_t buffer_size,
|
||||
const char *key, size_t key_size, const char *iv, size_t iv_size, int enc)
|
||||
static int cipher_perf_one(struct crypt_cipher_kernel *cipher, char *buffer, size_t buffer_size,
|
||||
const char *iv, size_t iv_size, int enc)
|
||||
{
|
||||
struct crypt_cipher_kernel cipher;
|
||||
size_t done = 0, block = CIPHER_BLOCK_BYTES;
|
||||
int r;
|
||||
|
||||
if (buffer_size < block)
|
||||
block = buffer_size;
|
||||
|
||||
r = crypt_cipher_init_kernel(&cipher, name, mode, key, key_size);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
while (done < buffer_size) {
|
||||
if ((done + block) > buffer_size)
|
||||
block = buffer_size - done;
|
||||
|
||||
if (enc)
|
||||
r = crypt_cipher_encrypt_kernel(&cipher, &buffer[done], &buffer[done],
|
||||
r = crypt_cipher_encrypt_kernel(cipher, &buffer[done], &buffer[done],
|
||||
block, iv, iv_size);
|
||||
else
|
||||
r = crypt_cipher_decrypt_kernel(&cipher, &buffer[done], &buffer[done],
|
||||
r = crypt_cipher_decrypt_kernel(cipher, &buffer[done], &buffer[done],
|
||||
block, iv, iv_size);
|
||||
if (r < 0)
|
||||
break;
|
||||
return r;
|
||||
|
||||
done += block;
|
||||
}
|
||||
|
||||
crypt_cipher_destroy_kernel(&cipher);
|
||||
|
||||
return r;
|
||||
return 0;
|
||||
}
|
||||
static int cipher_measure(const char *name, const char *mode, char *buffer, size_t buffer_size,
|
||||
const char *key, size_t key_size, const char *iv, size_t iv_size,
|
||||
int encrypt, double *ms)
|
||||
|
||||
static int cipher_measure(struct crypt_cipher_kernel *cipher, char *buffer, size_t buffer_size,
|
||||
const char *iv, size_t iv_size, int encrypt, double *ms)
|
||||
{
|
||||
struct timespec start, end;
|
||||
int r;
|
||||
@@ -103,7 +83,7 @@ static int cipher_measure(const char *name, const char *mode, char *buffer, size
|
||||
if (clock_gettime(CLOCK_MONOTONIC_RAW, &start) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
r = cipher_perf_one(name, mode, buffer, buffer_size, key, key_size, iv, iv_size, encrypt);
|
||||
r = cipher_perf_one(cipher, buffer, buffer_size, iv, iv_size, encrypt);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -131,15 +111,20 @@ int crypt_cipher_perf_kernel(const char *name, const char *mode, char *buffer, s
|
||||
const char *key, size_t key_size, const char *iv, size_t iv_size,
|
||||
double *encryption_mbs, double *decryption_mbs)
|
||||
{
|
||||
struct crypt_cipher_kernel cipher;
|
||||
double ms_enc, ms_dec, ms;
|
||||
int r, repeat_enc, repeat_dec;
|
||||
|
||||
r = crypt_cipher_init_kernel(&cipher, name, mode, key, key_size);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
ms_enc = 0.0;
|
||||
repeat_enc = 1;
|
||||
while (ms_enc < 1000.0) {
|
||||
r = cipher_measure(name, mode, buffer, buffer_size, key, key_size, iv, iv_size, 1, &ms);
|
||||
r = cipher_measure(&cipher, buffer, buffer_size, iv, iv_size, 1, &ms);
|
||||
if (r < 0)
|
||||
return r;
|
||||
goto out;
|
||||
ms_enc += ms;
|
||||
repeat_enc++;
|
||||
}
|
||||
@@ -147,9 +132,9 @@ int crypt_cipher_perf_kernel(const char *name, const char *mode, char *buffer, s
|
||||
ms_dec = 0.0;
|
||||
repeat_dec = 1;
|
||||
while (ms_dec < 1000.0) {
|
||||
r = cipher_measure(name, mode, buffer, buffer_size, key, key_size, iv, iv_size, 0, &ms);
|
||||
r = cipher_measure(&cipher, buffer, buffer_size, iv, iv_size, 0, &ms);
|
||||
if (r < 0)
|
||||
return r;
|
||||
goto out;
|
||||
ms_dec += ms;
|
||||
repeat_dec++;
|
||||
}
|
||||
@@ -157,5 +142,8 @@ int crypt_cipher_perf_kernel(const char *name, const char *mode, char *buffer, s
|
||||
*encryption_mbs = speed_mbs(buffer_size * repeat_enc, ms_enc);
|
||||
*decryption_mbs = speed_mbs(buffer_size * repeat_dec, ms_dec);
|
||||
|
||||
return 0;
|
||||
r = 0;
|
||||
out:
|
||||
crypt_cipher_destroy_kernel(&cipher);
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -1,27 +1,15 @@
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
/*
|
||||
* Linux kernel cipher generic utilities
|
||||
*
|
||||
* Copyright (C) 2018-2023 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2018-2023 Milan Broz
|
||||
*
|
||||
* 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.
|
||||
* Copyright (C) 2018-2025 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2018-2025 Milan Broz
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include <errno.h>
|
||||
#include <strings.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include "crypto_backend.h"
|
||||
|
||||
struct cipher_alg {
|
||||
@@ -76,6 +64,9 @@ int crypt_cipher_ivsize(const char *name, const char *mode)
|
||||
if (!ca)
|
||||
return -EINVAL;
|
||||
|
||||
if (mode && !strcasecmp(mode, "hctr2"))
|
||||
return 32;
|
||||
|
||||
if (mode && !strcasecmp(mode, "ecb"))
|
||||
return 0;
|
||||
|
||||
@@ -88,3 +79,21 @@ int crypt_cipher_wrapped_key(const char *name, const char *mode)
|
||||
|
||||
return ca ? (int)ca->wrapped_key : 0;
|
||||
}
|
||||
|
||||
bool crypt_fips_mode_kernel(void)
|
||||
{
|
||||
int fd;
|
||||
char buf = 0;
|
||||
|
||||
fd = open("/proc/sys/crypto/fips_enabled", O_RDONLY);
|
||||
|
||||
if (fd < 0)
|
||||
return false;
|
||||
|
||||
if (read(fd, &buf, 1) != 1)
|
||||
buf = '0';
|
||||
|
||||
close(fd);
|
||||
|
||||
return (buf == '1');
|
||||
}
|
||||
|
||||
@@ -38,8 +38,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "crypto_backend.h"
|
||||
|
||||
static const uint32_t crc32_tab[] = {
|
||||
|
||||
@@ -1,23 +1,11 @@
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
/*
|
||||
* crypto backend implementation
|
||||
*
|
||||
* Copyright (C) 2010-2023 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2023 Milan Broz
|
||||
*
|
||||
* 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.
|
||||
* Copyright (C) 2010-2025 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2025 Milan Broz
|
||||
*/
|
||||
|
||||
#ifndef _CRYPTO_BACKEND_H
|
||||
#define _CRYPTO_BACKEND_H
|
||||
|
||||
@@ -26,26 +14,32 @@
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#ifdef HAVE_UCHAR_H
|
||||
#if HAVE_UCHAR_H
|
||||
#include <uchar.h>
|
||||
#else
|
||||
#define char32_t uint32_t
|
||||
#define char16_t uint16_t
|
||||
#endif
|
||||
|
||||
# ifdef __cplusplus
|
||||
extern "C" {
|
||||
# endif
|
||||
|
||||
struct crypt_hash;
|
||||
struct crypt_hmac;
|
||||
struct crypt_cipher;
|
||||
struct crypt_storage;
|
||||
|
||||
int crypt_backend_init(bool fips);
|
||||
int crypt_backend_init(void);
|
||||
void crypt_backend_destroy(void);
|
||||
|
||||
#define CRYPT_BACKEND_KERNEL (1 << 0) /* Crypto uses kernel part, for benchmark */
|
||||
#define CRYPT_BACKEND_PBKDF2_INT (1 << 1) /* Iteration in PBKDF2 is signed int and can overflow */
|
||||
#define CRYPT_BACKEND_ARGON2 (1 << 2) /* Backend provides native Argon2 implementation */
|
||||
|
||||
uint32_t crypt_backend_flags(void);
|
||||
const char *crypt_backend_version(void);
|
||||
const char *crypt_argon2_version(void);
|
||||
|
||||
/* HASH */
|
||||
int crypt_hash_size(const char *name);
|
||||
@@ -99,6 +93,7 @@ int crypt_base64_decode(char **out, size_t *out_length, const char *in, size_t i
|
||||
/* UTF8/16 */
|
||||
int crypt_utf16_to_utf8(char **out, const char16_t *s, size_t length /* bytes! */);
|
||||
int crypt_utf8_to_utf16(char16_t **out, const char *s, size_t length);
|
||||
size_t crypt_char16_strlen(const char16_t *s);
|
||||
|
||||
/* Block ciphers */
|
||||
int crypt_cipher_ivsize(const char *name, const char *mode);
|
||||
@@ -142,15 +137,10 @@ int crypt_bitlk_decrypt_key(const void *key, size_t key_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)
|
||||
{
|
||||
#ifdef HAVE_EXPLICIT_BZERO
|
||||
explicit_bzero(s, n);
|
||||
#else
|
||||
volatile uint8_t *p = (volatile uint8_t *)s;
|
||||
while(n--) *p++ = 0;
|
||||
#endif
|
||||
}
|
||||
void crypt_backend_memzero(void *s, size_t n);
|
||||
|
||||
/* Memcpy helper to avoid spilling sensitive data through additional registers */
|
||||
void *crypt_backend_memcpy(void *dst, const void *src, size_t n);
|
||||
|
||||
/* Memcmp helper (memcmp in constant time) */
|
||||
int crypt_backend_memeq(const void *m1, const void *m2, size_t n);
|
||||
@@ -158,4 +148,11 @@ int crypt_backend_memeq(const void *m1, const void *m2, size_t n);
|
||||
/* crypto backend running in FIPS mode */
|
||||
bool crypt_fips_mode(void);
|
||||
|
||||
/* kernel running in FIPS mode */
|
||||
bool crypt_fips_mode_kernel(void);
|
||||
|
||||
# ifdef __cplusplus
|
||||
}
|
||||
# endif
|
||||
|
||||
#endif /* _CRYPTO_BACKEND_H */
|
||||
|
||||
@@ -1,29 +1,17 @@
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
/*
|
||||
* crypto backend implementation
|
||||
*
|
||||
* Copyright (C) 2010-2023 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2023 Milan Broz
|
||||
*
|
||||
* 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.
|
||||
* Copyright (C) 2010-2025 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2025 Milan Broz
|
||||
*/
|
||||
|
||||
#ifndef _CRYPTO_BACKEND_INTERNAL_H
|
||||
#define _CRYPTO_BACKEND_INTERNAL_H
|
||||
|
||||
#include "crypto_backend.h"
|
||||
|
||||
/* internal PBKDF2 implementation */
|
||||
/* Internal PBKDF2 implementation */
|
||||
int pkcs5_pbkdf2(const char *hash,
|
||||
const char *P, size_t Plen,
|
||||
const char *S, size_t Slen,
|
||||
@@ -59,17 +47,6 @@ int crypt_bitlk_decrypt_key_kernel(const void *key, size_t key_length,
|
||||
const char *tag, size_t tag_length);
|
||||
|
||||
/* Internal implementation for constant time memory comparison */
|
||||
static inline int crypt_internal_memeq(const void *m1, const void *m2, size_t n)
|
||||
{
|
||||
const unsigned char *_m1 = (const unsigned char *) m1;
|
||||
const unsigned char *_m2 = (const unsigned char *) m2;
|
||||
unsigned char result = 0;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
result |= _m1[i] ^ _m2[i];
|
||||
|
||||
return result;
|
||||
}
|
||||
int crypt_internal_memeq(const void *m1, const void *m2, size_t n);
|
||||
|
||||
#endif /* _CRYPTO_BACKEND_INTERNAL_H */
|
||||
|
||||
@@ -1,35 +1,20 @@
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
/*
|
||||
* Linux kernel userspace API crypto backend implementation (skcipher)
|
||||
*
|
||||
* Copyright (C) 2012-2023 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2023 Milan Broz
|
||||
*
|
||||
* 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.
|
||||
* Copyright (C) 2012-2025 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2025 Milan Broz
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include "crypto_backend_internal.h"
|
||||
|
||||
#ifdef ENABLE_AF_ALG
|
||||
#if ENABLE_AF_ALG
|
||||
|
||||
#include <linux/if_alg.h>
|
||||
|
||||
@@ -55,6 +40,8 @@ static int _crypt_cipher_init(struct crypt_cipher_kernel *ctx,
|
||||
const void *key, size_t key_length,
|
||||
size_t tag_length, struct sockaddr_alg *sa)
|
||||
{
|
||||
void *optval = NULL;
|
||||
|
||||
if (!ctx)
|
||||
return -EINVAL;
|
||||
|
||||
@@ -75,7 +62,7 @@ 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) {
|
||||
if (tag_length && setsockopt(ctx->tfmfd, SOL_ALG, ALG_SET_AEAD_AUTHSIZE, &optval, tag_length) < 0) {
|
||||
crypt_cipher_destroy_kernel(ctx);
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -101,13 +88,31 @@ int crypt_cipher_init_kernel(struct crypt_cipher_kernel *ctx, const char *name,
|
||||
if (!strcmp(name, "cipher_null"))
|
||||
key_length = 0;
|
||||
|
||||
r = snprintf((char *)sa.salg_name, sizeof(sa.salg_name), "%s(%s)", mode, name);
|
||||
if (r < 0 || (size_t)r >= sizeof(sa.salg_name))
|
||||
return -EINVAL;
|
||||
if (!strncmp(name, "capi:", 5))
|
||||
strncpy((char *)sa.salg_name, &name[5], sizeof(sa.salg_name) - 1);
|
||||
else {
|
||||
r = snprintf((char *)sa.salg_name, sizeof(sa.salg_name), "%s(%s)", mode, name);
|
||||
if (r < 0 || (size_t)r >= sizeof(sa.salg_name))
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return _crypt_cipher_init(ctx, key, key_length, 0, &sa);
|
||||
}
|
||||
|
||||
/* musl has broken CMSG_NXTHDR macro in system headers */
|
||||
static inline struct cmsghdr *_CMSG_NXTHDR(struct msghdr* mhdr, struct cmsghdr* cmsg)
|
||||
{
|
||||
#if !defined(__GLIBC__) && defined(__clang__)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wcast-align"
|
||||
#pragma clang diagnostic ignored "-Wsign-compare"
|
||||
return CMSG_NXTHDR(mhdr, cmsg);
|
||||
#pragma clang diagnostic pop
|
||||
#else
|
||||
return CMSG_NXTHDR(mhdr, cmsg);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* The in/out should be aligned to page boundary */
|
||||
/* coverity[ -taint_source : arg-3 ] */
|
||||
static int _crypt_cipher_crypt(struct crypt_cipher_kernel *ctx,
|
||||
@@ -155,7 +160,7 @@ static int _crypt_cipher_crypt(struct crypt_cipher_kernel *ctx,
|
||||
|
||||
/* Set IV */
|
||||
if (iv) {
|
||||
header = CMSG_NXTHDR(&msg, header);
|
||||
header = _CMSG_NXTHDR(&msg, header);
|
||||
if (!header)
|
||||
return -EINVAL;
|
||||
|
||||
@@ -164,7 +169,7 @@ static int _crypt_cipher_crypt(struct crypt_cipher_kernel *ctx,
|
||||
header->cmsg_len = iv_msg_size;
|
||||
alg_iv = (void*)CMSG_DATA(header);
|
||||
alg_iv->ivlen = iv_length;
|
||||
memcpy(alg_iv->iv, iv, iv_length);
|
||||
crypt_backend_memcpy(alg_iv->iv, iv, iv_length);
|
||||
}
|
||||
|
||||
len = sendmsg(ctx->opfd, &msg, 0);
|
||||
@@ -211,8 +216,8 @@ int crypt_cipher_check_kernel(const char *name, const char *mode,
|
||||
const char *integrity, size_t key_length)
|
||||
{
|
||||
struct crypt_cipher_kernel c;
|
||||
char mode_name[64], tmp_salg_name[180], *real_mode = NULL, *cipher_iv = NULL, *key;
|
||||
const char *salg_type;
|
||||
char mode_name[64], tmp_salg_name[180], *cipher_iv = NULL, *key;
|
||||
const char *salg_type, *real_mode;
|
||||
bool aead;
|
||||
int r;
|
||||
struct sockaddr_alg sa = {
|
||||
@@ -220,6 +225,7 @@ int crypt_cipher_check_kernel(const char *name, const char *mode,
|
||||
};
|
||||
|
||||
aead = integrity && strcmp(integrity, "none");
|
||||
real_mode = NULL;
|
||||
|
||||
/* Remove IV if present */
|
||||
if (mode) {
|
||||
@@ -240,14 +246,22 @@ int crypt_cipher_check_kernel(const char *name, const char *mode,
|
||||
memset(tmp_salg_name, 0, sizeof(tmp_salg_name));
|
||||
|
||||
/* FIXME: this is duplicating a part of devmapper backend */
|
||||
if (aead && !strcmp(integrity, "poly1305"))
|
||||
r = snprintf(tmp_salg_name, sizeof(tmp_salg_name), "rfc7539(%s,%s)", name, integrity);
|
||||
else if (!real_mode)
|
||||
r = snprintf(tmp_salg_name, sizeof(tmp_salg_name), "%s", name);
|
||||
else if (aead && !strcmp(real_mode, "ccm"))
|
||||
r = snprintf(tmp_salg_name, sizeof(tmp_salg_name), "rfc4309(%s(%s))", real_mode, name);
|
||||
else
|
||||
r = snprintf(tmp_salg_name, sizeof(tmp_salg_name), "%s(%s)", real_mode, name);
|
||||
if (aead) {
|
||||
/* In AEAD, mode parameter can be just IV like "random" */
|
||||
if (!strcmp(integrity, "poly1305"))
|
||||
r = snprintf(tmp_salg_name, sizeof(tmp_salg_name), "rfc7539(%s,%s)", name, integrity);
|
||||
else if (!real_mode)
|
||||
r = snprintf(tmp_salg_name, sizeof(tmp_salg_name), "%s", name);
|
||||
else if (!strcmp(real_mode, "ccm"))
|
||||
r = snprintf(tmp_salg_name, sizeof(tmp_salg_name), "rfc4309(%s(%s))", real_mode, name);
|
||||
else
|
||||
r = snprintf(tmp_salg_name, sizeof(tmp_salg_name), "%s(%s)", real_mode, name);
|
||||
} else {
|
||||
if (!mode)
|
||||
r = snprintf(tmp_salg_name, sizeof(tmp_salg_name), "%s", name);
|
||||
else
|
||||
r = snprintf(tmp_salg_name, sizeof(tmp_salg_name), "%s(%s)", real_mode ?: mode_name, name);
|
||||
}
|
||||
|
||||
if (r < 0 || (size_t)r >= sizeof(tmp_salg_name))
|
||||
return -EINVAL;
|
||||
|
||||
@@ -1,27 +1,14 @@
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
/*
|
||||
* GCRYPT crypto backend implementation
|
||||
*
|
||||
* Copyright (C) 2010-2023 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2023 Milan Broz
|
||||
*
|
||||
* 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.
|
||||
* Copyright (C) 2010-2025 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2025 Milan Broz
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <strings.h>
|
||||
#include <gcrypt.h>
|
||||
#include <pthread.h>
|
||||
#include "crypto_backend_internal.h"
|
||||
@@ -64,7 +51,6 @@ static void crypt_hash_test_whirlpool_bug(void)
|
||||
{
|
||||
struct crypt_hash *h;
|
||||
char buf[2] = "\0\0", hash_out1[64], hash_out2[64];
|
||||
int r;
|
||||
|
||||
if (crypto_backend_whirlpool_bug >= 0)
|
||||
return;
|
||||
@@ -74,16 +60,16 @@ static void crypt_hash_test_whirlpool_bug(void)
|
||||
return;
|
||||
|
||||
/* One shot */
|
||||
if ((r = crypt_hash_write(h, &buf[0], 2)) ||
|
||||
(r = crypt_hash_final(h, hash_out1, 64))) {
|
||||
if (crypt_hash_write(h, &buf[0], 2) ||
|
||||
crypt_hash_final(h, hash_out1, 64)) {
|
||||
crypt_hash_destroy(h);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Split buf (crypt_hash_final resets hash state) */
|
||||
if ((r = crypt_hash_write(h, &buf[0], 1)) ||
|
||||
(r = crypt_hash_write(h, &buf[1], 1)) ||
|
||||
(r = crypt_hash_final(h, hash_out2, 64))) {
|
||||
if (crypt_hash_write(h, &buf[0], 1) ||
|
||||
crypt_hash_write(h, &buf[1], 1) ||
|
||||
crypt_hash_final(h, hash_out2, 64)) {
|
||||
crypt_hash_destroy(h);
|
||||
return;
|
||||
}
|
||||
@@ -94,7 +80,7 @@ static void crypt_hash_test_whirlpool_bug(void)
|
||||
crypto_backend_whirlpool_bug = 1;
|
||||
}
|
||||
|
||||
int crypt_backend_init(bool fips __attribute__((unused)))
|
||||
int crypt_backend_init(void)
|
||||
{
|
||||
int r;
|
||||
|
||||
@@ -127,10 +113,11 @@ int crypt_backend_init(bool fips __attribute__((unused)))
|
||||
crypto_backend_initialised = 1;
|
||||
crypt_hash_test_whirlpool_bug();
|
||||
|
||||
r = snprintf(version, sizeof(version), "gcrypt %s%s%s",
|
||||
r = snprintf(version, sizeof(version), "gcrypt %s%s%s%s",
|
||||
gcry_check_version(NULL),
|
||||
crypto_backend_secmem ? "" : ", secmem disabled",
|
||||
crypto_backend_whirlpool_bug > 0 ? ", flawed whirlpool" : "");
|
||||
crypto_backend_whirlpool_bug > 0 ? ", flawed whirlpool" : "",
|
||||
crypt_backend_flags() & CRYPT_BACKEND_ARGON2 ? ", argon2" : "");
|
||||
if (r < 0 || (size_t)r >= sizeof(version))
|
||||
return -EINVAL;
|
||||
|
||||
@@ -152,7 +139,11 @@ const char *crypt_backend_version(void)
|
||||
|
||||
uint32_t crypt_backend_flags(void)
|
||||
{
|
||||
return 0;
|
||||
uint32_t flags = 0;
|
||||
#if HAVE_DECL_GCRY_KDF_ARGON2 && !USE_INTERNAL_ARGON2
|
||||
flags |= CRYPT_BACKEND_ARGON2;
|
||||
#endif
|
||||
return flags;
|
||||
}
|
||||
|
||||
static const char *crypt_hash_compat_name(const char *name, unsigned int *flags)
|
||||
@@ -258,7 +249,7 @@ int crypt_hash_final(struct crypt_hash *ctx, char *buffer, size_t length)
|
||||
if (!hash)
|
||||
return -EINVAL;
|
||||
|
||||
memcpy(buffer, hash, length);
|
||||
crypt_backend_memcpy(buffer, hash, length);
|
||||
crypt_hash_restart(ctx);
|
||||
|
||||
return 0;
|
||||
@@ -332,7 +323,7 @@ int crypt_hmac_final(struct crypt_hmac *ctx, char *buffer, size_t length)
|
||||
if (!hash)
|
||||
return -EINVAL;
|
||||
|
||||
memcpy(buffer, hash, length);
|
||||
crypt_backend_memcpy(buffer, hash, length);
|
||||
crypt_hmac_restart(ctx);
|
||||
|
||||
return 0;
|
||||
@@ -460,6 +451,7 @@ static int gcrypt_argon2(const char *type,
|
||||
.dispatch_job = gcrypt_dispatch_job,
|
||||
.wait_all_jobs = gcrypt_wait_all_jobs
|
||||
};
|
||||
gpg_error_t err;
|
||||
|
||||
if (!strcmp(type, "argon2i"))
|
||||
atype = GCRY_KDF_ARGON2I;
|
||||
@@ -473,12 +465,11 @@ static int gcrypt_argon2(const char *type,
|
||||
param[2] = memory;
|
||||
param[3] = parallel;
|
||||
|
||||
if (gcry_kdf_open(&hd, GCRY_KDF_ARGON2, atype, param, 4,
|
||||
err = gcry_kdf_open(&hd, GCRY_KDF_ARGON2, atype, param, 4,
|
||||
password, password_length, salt, salt_length,
|
||||
NULL, 0, NULL, 0)) {
|
||||
free(threads.jobs_ctx);
|
||||
return -EINVAL;
|
||||
}
|
||||
NULL, 0, NULL, 0);
|
||||
if (err)
|
||||
return ((err & GPG_ERR_CODE_MASK) == GPG_ERR_ENOMEM) ? -ENOMEM : -EINVAL;
|
||||
|
||||
if (parallel == 1) {
|
||||
/* Do not use threads here */
|
||||
@@ -693,7 +684,7 @@ bool crypt_fips_mode(void)
|
||||
if (fips_checked)
|
||||
return fips_mode;
|
||||
|
||||
if (crypt_backend_init(false /* ignored */))
|
||||
if (crypt_backend_init())
|
||||
return false;
|
||||
|
||||
fips_mode = gcry_fips_mode_active();
|
||||
|
||||
@@ -1,25 +1,11 @@
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
/*
|
||||
* Linux kernel userspace API crypto backend implementation
|
||||
*
|
||||
* Copyright (C) 2010-2023 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2023 Milan Broz
|
||||
*
|
||||
* 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.
|
||||
* Copyright (C) 2010-2025 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2025 Milan Broz
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
@@ -117,7 +103,7 @@ static int crypt_kernel_socket_init(struct sockaddr_alg *sa, int *tfmfd, int *op
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypt_backend_init(bool fips __attribute__((unused)))
|
||||
int crypt_backend_init(void)
|
||||
{
|
||||
struct utsname uts;
|
||||
struct sockaddr_alg sa = {
|
||||
@@ -422,5 +408,5 @@ int crypt_backend_memeq(const void *m1, const void *m2, size_t n)
|
||||
|
||||
bool crypt_fips_mode(void)
|
||||
{
|
||||
return false;
|
||||
return crypt_fips_mode_kernel();
|
||||
}
|
||||
|
||||
532
lib/crypto_backend/crypto_mbedtls.c
Normal file
532
lib/crypto_backend/crypto_mbedtls.c
Normal file
@@ -0,0 +1,532 @@
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
/*
|
||||
* Mbed TLS crypto backend implementation
|
||||
*
|
||||
* Copyright (C) 2024-2025 Yiyuan Zhong
|
||||
*/
|
||||
|
||||
#include "crypto_backend.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <mbedtls/ccm.h>
|
||||
#include <mbedtls/constant_time.h>
|
||||
#include <mbedtls/cipher.h>
|
||||
#include <mbedtls/ctr_drbg.h>
|
||||
#include <mbedtls/entropy.h>
|
||||
#include <mbedtls/md.h>
|
||||
#include <mbedtls/pkcs5.h>
|
||||
#include <mbedtls/version.h>
|
||||
|
||||
#include "crypto_backend_internal.h"
|
||||
|
||||
struct crypt_hash {
|
||||
const mbedtls_md_info_t *info;
|
||||
mbedtls_md_context_t md;
|
||||
};
|
||||
|
||||
struct crypt_hmac {
|
||||
const mbedtls_md_info_t *info;
|
||||
mbedtls_md_context_t md;
|
||||
};
|
||||
|
||||
struct crypt_cipher {
|
||||
const mbedtls_cipher_info_t *info;
|
||||
mbedtls_cipher_context_t enc;
|
||||
mbedtls_cipher_context_t dec;
|
||||
int ecb;
|
||||
};
|
||||
|
||||
static bool g_initialized = false;
|
||||
static char g_backend_version[32];
|
||||
static mbedtls_entropy_context g_entropy;
|
||||
static mbedtls_ctr_drbg_context g_ctr_drbg;
|
||||
|
||||
static const mbedtls_md_info_t *crypt_get_hash(const char *name)
|
||||
{
|
||||
static const struct hash_alg {
|
||||
const char *name;
|
||||
mbedtls_md_type_t type;
|
||||
} kHash[] = {
|
||||
{"sha1", MBEDTLS_MD_SHA1 },
|
||||
{"sha224", MBEDTLS_MD_SHA224 },
|
||||
{"sha256", MBEDTLS_MD_SHA256 },
|
||||
{"sha384", MBEDTLS_MD_SHA384 },
|
||||
{"sha512", MBEDTLS_MD_SHA512 },
|
||||
{"ripemd160", MBEDTLS_MD_RIPEMD160},
|
||||
{NULL, 0, }
|
||||
};
|
||||
|
||||
size_t i = 0;
|
||||
|
||||
while (name && kHash[i].name) {
|
||||
if (strcmp(kHash[i].name, name) == 0)
|
||||
return mbedtls_md_info_from_type(kHash[i].type);
|
||||
i++;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int crypt_backend_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (g_initialized)
|
||||
return 0;
|
||||
|
||||
mbedtls_version_get_string_full(g_backend_version);
|
||||
|
||||
mbedtls_entropy_init(&g_entropy);
|
||||
mbedtls_ctr_drbg_init(&g_ctr_drbg);
|
||||
|
||||
ret = mbedtls_ctr_drbg_seed(
|
||||
&g_ctr_drbg, mbedtls_entropy_func,
|
||||
&g_entropy, NULL, MBEDTLS_CTR_DRBG_ENTROPY_LEN);
|
||||
|
||||
if (ret)
|
||||
return -EINVAL;
|
||||
|
||||
g_initialized = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void crypt_backend_destroy(void)
|
||||
{
|
||||
if (!g_initialized)
|
||||
return;
|
||||
|
||||
mbedtls_ctr_drbg_free(&g_ctr_drbg);
|
||||
mbedtls_entropy_free(&g_entropy);
|
||||
g_initialized = false;
|
||||
}
|
||||
|
||||
uint32_t crypt_backend_flags(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *crypt_backend_version(void)
|
||||
{
|
||||
return g_backend_version;
|
||||
}
|
||||
|
||||
bool crypt_fips_mode(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int crypt_backend_memeq(const void *m1, const void *m2, size_t n)
|
||||
{
|
||||
return mbedtls_ct_memcmp(m1, m2, n);
|
||||
}
|
||||
|
||||
/* HASH */
|
||||
int crypt_hash_size(const char *name)
|
||||
{
|
||||
const mbedtls_md_info_t *info;
|
||||
info = crypt_get_hash(name);
|
||||
return info ? mbedtls_md_get_size(info) : -ENOENT;
|
||||
}
|
||||
|
||||
int crypt_hash_init(struct crypt_hash **ctx, const char *name)
|
||||
{
|
||||
struct crypt_hash *h;
|
||||
|
||||
h = malloc(sizeof(*h));
|
||||
if (!h)
|
||||
return -ENOMEM;
|
||||
|
||||
h->info = crypt_get_hash(name);
|
||||
if (!h->info) {
|
||||
free(h);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
mbedtls_md_init(&h->md);
|
||||
|
||||
if (mbedtls_md_setup(&h->md, h->info, 0)) {
|
||||
mbedtls_md_free(&h->md);
|
||||
free(h);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (mbedtls_md_starts(&h->md)) {
|
||||
mbedtls_md_free(&h->md);
|
||||
free(h);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
*ctx = h;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypt_hash_write(struct crypt_hash *ctx, const char *buffer, size_t length)
|
||||
{
|
||||
if (mbedtls_md_update(&ctx->md, (const unsigned char *)buffer, length))
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypt_hash_final(struct crypt_hash *ctx, char *buffer, size_t length)
|
||||
{
|
||||
unsigned char tmp[MBEDTLS_MD_MAX_SIZE];
|
||||
|
||||
if (length > mbedtls_md_get_size(ctx->info))
|
||||
return -EINVAL;
|
||||
|
||||
if (mbedtls_md_finish(&ctx->md, tmp))
|
||||
return -EINVAL;
|
||||
|
||||
crypt_backend_memcpy(buffer, tmp, length);
|
||||
crypt_backend_memzero(tmp, sizeof(tmp));
|
||||
|
||||
if (mbedtls_md_starts(&ctx->md))
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void crypt_hash_destroy(struct crypt_hash *ctx)
|
||||
{
|
||||
mbedtls_md_free(&ctx->md);
|
||||
crypt_backend_memzero(ctx, sizeof(*ctx));
|
||||
free(ctx);
|
||||
}
|
||||
|
||||
/* HMAC */
|
||||
int crypt_hmac_size(const char *name)
|
||||
{
|
||||
return crypt_hash_size(name);
|
||||
}
|
||||
|
||||
int crypt_hmac_init(struct crypt_hmac **ctx, const char *name,
|
||||
const void *key, size_t key_length)
|
||||
{
|
||||
struct crypt_hmac *h;
|
||||
|
||||
h = malloc(sizeof(*h));
|
||||
if (!h)
|
||||
return -ENOMEM;
|
||||
|
||||
h->info = crypt_get_hash(name);
|
||||
if (!h->info) {
|
||||
free(h);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
mbedtls_md_init(&h->md);
|
||||
|
||||
if (mbedtls_md_setup(&h->md, h->info, 1)) {
|
||||
mbedtls_md_free(&h->md);
|
||||
free(h);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (mbedtls_md_hmac_starts(&h->md, key, key_length)) {
|
||||
mbedtls_md_free(&h->md);
|
||||
free(h);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
*ctx = h;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypt_hmac_write(struct crypt_hmac *ctx, const char *buffer, size_t length)
|
||||
{
|
||||
if (mbedtls_md_hmac_update(&ctx->md, (const unsigned char *)buffer, length))
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypt_hmac_final(struct crypt_hmac *ctx, char *buffer, size_t length)
|
||||
{
|
||||
unsigned char tmp[MBEDTLS_MD_MAX_SIZE];
|
||||
|
||||
if (length > mbedtls_md_get_size(ctx->info))
|
||||
return -EINVAL;
|
||||
|
||||
if (mbedtls_md_hmac_finish(&ctx->md, tmp))
|
||||
return -EINVAL;
|
||||
|
||||
crypt_backend_memcpy(buffer, tmp, length);
|
||||
crypt_backend_memzero(tmp, sizeof(tmp));
|
||||
|
||||
if (mbedtls_md_hmac_reset(&ctx->md))
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void crypt_hmac_destroy(struct crypt_hmac *ctx)
|
||||
{
|
||||
mbedtls_md_free(&ctx->md);
|
||||
crypt_backend_memzero(ctx, sizeof(*ctx));
|
||||
free(ctx);
|
||||
}
|
||||
|
||||
/* RNG */
|
||||
int crypt_backend_rng(char *buffer, size_t length, int quality, int fips)
|
||||
{
|
||||
if (fips)
|
||||
return -ENOTSUP;
|
||||
|
||||
/* Allow skipping reseeding for non-cryptographic strong random numbers */
|
||||
if (quality == CRYPT_RND_NORMAL || quality == CRYPT_RND_SALT)
|
||||
mbedtls_ctr_drbg_set_prediction_resistance(&g_ctr_drbg, MBEDTLS_CTR_DRBG_PR_OFF);
|
||||
else
|
||||
mbedtls_ctr_drbg_set_prediction_resistance(&g_ctr_drbg, MBEDTLS_CTR_DRBG_PR_ON);
|
||||
|
||||
if (mbedtls_ctr_drbg_random(&g_ctr_drbg, (unsigned char *)buffer, length))
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* CIPHER */
|
||||
int crypt_cipher_init(struct crypt_cipher **ctx, const char *name,
|
||||
const char *mode, const void *key, size_t key_length)
|
||||
{
|
||||
static const struct {
|
||||
const char *name;
|
||||
mbedtls_cipher_id_t id;
|
||||
} kCipher[] = {
|
||||
{ "aes", MBEDTLS_CIPHER_ID_AES },
|
||||
{ "aria", MBEDTLS_CIPHER_ID_ARIA },
|
||||
{ "camellia", MBEDTLS_CIPHER_ID_CAMELLIA },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
static const struct {
|
||||
const char *name;
|
||||
mbedtls_cipher_mode_t mode;
|
||||
} kMode[] = {
|
||||
{ "ecb", MBEDTLS_MODE_ECB },
|
||||
{ "cbc", MBEDTLS_MODE_CBC },
|
||||
{ "cfb", MBEDTLS_MODE_CFB },
|
||||
{ "ofb", MBEDTLS_MODE_OFB },
|
||||
{ "ctr", MBEDTLS_MODE_CTR },
|
||||
{ "xts", MBEDTLS_MODE_XTS },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
mbedtls_cipher_id_t cid = MBEDTLS_CIPHER_ID_NONE;
|
||||
mbedtls_cipher_mode_t cmode = MBEDTLS_MODE_NONE;
|
||||
struct crypt_cipher *h;
|
||||
size_t i;
|
||||
int bits;
|
||||
|
||||
for (i = 0; kCipher[i].name; i++) {
|
||||
if (strcmp(kCipher[i].name, name) == 0) {
|
||||
cid = kCipher[i].id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; kMode[i].name; i++) {
|
||||
if (strcmp(kMode[i].name, mode) == 0) {
|
||||
cmode = kMode[i].mode;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (cid == MBEDTLS_CIPHER_ID_NONE || cmode == MBEDTLS_MODE_NONE)
|
||||
return -ENOENT;
|
||||
|
||||
h = malloc(sizeof(*h));
|
||||
if (!h)
|
||||
return -ENOMEM;
|
||||
|
||||
bits = key_length * 8;
|
||||
h->info = mbedtls_cipher_info_from_values(cid, bits, cmode);
|
||||
if (!h->info) {
|
||||
free(h);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
mbedtls_cipher_init(&h->enc);
|
||||
mbedtls_cipher_init(&h->dec);
|
||||
if (mbedtls_cipher_setup(&h->enc, h->info) ||
|
||||
mbedtls_cipher_setup(&h->dec, h->info) ||
|
||||
mbedtls_cipher_setkey(&h->enc, key, bits, MBEDTLS_ENCRYPT) ||
|
||||
mbedtls_cipher_setkey(&h->dec, key, bits, MBEDTLS_DECRYPT)) {
|
||||
|
||||
mbedtls_cipher_free(&h->dec);
|
||||
mbedtls_cipher_free(&h->enc);
|
||||
free(h);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (cmode == MBEDTLS_MODE_CBC) {
|
||||
if (mbedtls_cipher_set_padding_mode(&h->enc, MBEDTLS_PADDING_NONE) ||
|
||||
mbedtls_cipher_set_padding_mode(&h->dec, MBEDTLS_PADDING_NONE)) {
|
||||
|
||||
mbedtls_cipher_free(&h->dec);
|
||||
mbedtls_cipher_free(&h->enc);
|
||||
free(h);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
h->ecb = cmode == MBEDTLS_MODE_ECB;
|
||||
*ctx = h;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void crypt_cipher_destroy(struct crypt_cipher *ctx)
|
||||
{
|
||||
mbedtls_cipher_free(&ctx->dec);
|
||||
mbedtls_cipher_free(&ctx->enc);
|
||||
free(ctx);
|
||||
}
|
||||
|
||||
static int crypt_cipher_crypt(
|
||||
mbedtls_cipher_context_t *ctx,
|
||||
const char *in, char *out, size_t length,
|
||||
const char *iv, size_t iv_length,
|
||||
int ecb)
|
||||
{
|
||||
const unsigned char *input;
|
||||
unsigned char *output;
|
||||
size_t outlen;
|
||||
size_t block;
|
||||
size_t len;
|
||||
|
||||
if (ecb) /* ECB requires exactly block length input */
|
||||
block = mbedtls_cipher_get_block_size(ctx);
|
||||
else
|
||||
block = length;
|
||||
|
||||
input = (const unsigned char *)in;
|
||||
output = (unsigned char *)out;
|
||||
|
||||
if (mbedtls_cipher_set_iv(ctx, (const unsigned char *)iv, iv_length))
|
||||
return -EINVAL;
|
||||
|
||||
if (mbedtls_cipher_reset(ctx))
|
||||
return -EINVAL;
|
||||
|
||||
while (length) {
|
||||
len = length < block ? length : block;
|
||||
if (mbedtls_cipher_update(ctx, input, len, output, &outlen))
|
||||
return -EINVAL;
|
||||
|
||||
output += outlen;
|
||||
length -= len;
|
||||
input += len;
|
||||
}
|
||||
|
||||
if (mbedtls_cipher_finish(ctx, output, &outlen))
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypt_cipher_encrypt(struct crypt_cipher *ctx,
|
||||
const char *in, char *out, size_t length,
|
||||
const char *iv, size_t iv_length)
|
||||
{
|
||||
return crypt_cipher_crypt(&ctx->enc, in, out, length, iv, iv_length, ctx->ecb);
|
||||
}
|
||||
|
||||
int crypt_cipher_decrypt(struct crypt_cipher *ctx,
|
||||
const char *in, char *out, size_t length,
|
||||
const char *iv, size_t iv_length)
|
||||
{
|
||||
return crypt_cipher_crypt(&ctx->dec, in, out, length, iv, iv_length, ctx->ecb);
|
||||
}
|
||||
|
||||
bool crypt_cipher_kernel_only(struct crypt_cipher *ctx __attribute__((unused)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int crypt_pbkdf(const char *kdf, const char *hash,
|
||||
const char *password, size_t password_length,
|
||||
const char *salt, size_t salt_length,
|
||||
char *key, size_t key_length,
|
||||
uint32_t iterations, uint32_t memory, uint32_t parallel)
|
||||
{
|
||||
const mbedtls_md_info_t *info;
|
||||
#if !HAVE_MBEDTLS_PKCS5_PBKDF2_HMAC_EXT
|
||||
mbedtls_md_context_t md;
|
||||
#endif
|
||||
|
||||
if (!kdf)
|
||||
return -EINVAL;
|
||||
|
||||
if (strcmp(kdf, "pbkdf2") == 0) {
|
||||
info = crypt_get_hash(hash);
|
||||
if (!info)
|
||||
return -EINVAL;
|
||||
|
||||
#if HAVE_MBEDTLS_PKCS5_PBKDF2_HMAC_EXT
|
||||
if (mbedtls_pkcs5_pbkdf2_hmac_ext(mbedtls_md_get_type(info),
|
||||
(const unsigned char *)password, password_length,
|
||||
(const unsigned char *)salt, salt_length,
|
||||
iterations, key_length, (unsigned char *)key)) {
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
#else
|
||||
mbedtls_md_init(&md);
|
||||
if (mbedtls_md_setup(&md, info, 1))
|
||||
return -EINVAL;
|
||||
|
||||
if (mbedtls_pkcs5_pbkdf2_hmac(&md,
|
||||
(const unsigned char *)password, password_length,
|
||||
(const unsigned char *)salt, salt_length,
|
||||
iterations, key_length, (unsigned char *)key)) {
|
||||
|
||||
mbedtls_md_free(&md);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mbedtls_md_free(&md);
|
||||
#endif
|
||||
return 0;
|
||||
|
||||
} else if (strncmp(kdf, "argon2", 6) == 0) {
|
||||
return argon2(kdf, password, password_length, salt, salt_length,
|
||||
key, key_length, iterations, memory, parallel);
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
const unsigned char *tagptr;
|
||||
const unsigned char *input;
|
||||
const unsigned char *ivptr;
|
||||
mbedtls_ccm_context ctx;
|
||||
unsigned char *output;
|
||||
|
||||
tagptr = (const unsigned char *)tag;
|
||||
ivptr = (const unsigned char *)iv;
|
||||
input = (const unsigned char *)in;
|
||||
output = (unsigned char *)out;
|
||||
mbedtls_ccm_init(&ctx);
|
||||
|
||||
if (mbedtls_ccm_setkey(&ctx, MBEDTLS_CIPHER_ID_AES, key, key_length * 8)) {
|
||||
mbedtls_ccm_free(&ctx);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (mbedtls_ccm_auth_decrypt(&ctx, length, ivptr, iv_length, NULL, 0,
|
||||
input, output, tagptr, tag_length)) {
|
||||
|
||||
mbedtls_ccm_free(&ctx);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mbedtls_ccm_free(&ctx);
|
||||
return 0;
|
||||
}
|
||||
@@ -1,26 +1,12 @@
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
/*
|
||||
* Nettle crypto backend implementation
|
||||
*
|
||||
* Copyright (C) 2011-2023 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2011-2023 Milan Broz
|
||||
*
|
||||
* 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.
|
||||
* Copyright (C) 2011-2025 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2011-2025 Milan Broz
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <nettle/sha.h>
|
||||
#include <nettle/sha3.h>
|
||||
@@ -214,7 +200,7 @@ static struct hash_alg *_get_alg(const char *name)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int crypt_backend_init(bool fips __attribute__((unused)))
|
||||
int crypt_backend_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -298,8 +284,7 @@ int crypt_hmac_init(struct crypt_hmac **ctx, const char *name,
|
||||
h = malloc(sizeof(*h));
|
||||
if (!h)
|
||||
return -ENOMEM;
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
|
||||
memset(h, 0, sizeof(*h));
|
||||
|
||||
h->hash = _get_alg(name);
|
||||
if (!h->hash) {
|
||||
@@ -313,7 +298,7 @@ int crypt_hmac_init(struct crypt_hmac **ctx, const char *name,
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
memcpy(h->key, key, key_length);
|
||||
crypt_backend_memcpy(h->key, key, key_length);
|
||||
h->key_length = key_length;
|
||||
|
||||
h->hash->init(&h->nettle_ctx);
|
||||
|
||||
@@ -1,25 +1,12 @@
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
/*
|
||||
* NSS crypto backend implementation
|
||||
*
|
||||
* Copyright (C) 2010-2023 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2023 Milan Broz
|
||||
*
|
||||
* 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.
|
||||
* Copyright (C) 2010-2025 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2025 Milan Broz
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <nss.h>
|
||||
#include <pk11pub.h>
|
||||
@@ -75,7 +62,7 @@ static struct hash_alg *_get_alg(const char *name)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int crypt_backend_init(bool fips __attribute__((unused)))
|
||||
int crypt_backend_init(void)
|
||||
{
|
||||
int r;
|
||||
|
||||
@@ -177,7 +164,7 @@ int crypt_hash_final(struct crypt_hash *ctx, char *buffer, size_t length)
|
||||
if (PK11_DigestFinal(ctx->md, tmp, &tmp_len, length) != SECSuccess)
|
||||
return -EINVAL;
|
||||
|
||||
memcpy(buffer, tmp, length);
|
||||
crypt_backend_memcpy(buffer, tmp, length);
|
||||
crypt_backend_memzero(tmp, sizeof(tmp));
|
||||
|
||||
if (tmp_len < length)
|
||||
@@ -220,8 +207,7 @@ int crypt_hmac_init(struct crypt_hmac **ctx, const char *name,
|
||||
h = malloc(sizeof(*h));
|
||||
if (!h)
|
||||
return -ENOMEM;
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
|
||||
memset(h, 0, sizeof(*h));
|
||||
|
||||
h->hash = _get_alg(name);
|
||||
if (!h->hash)
|
||||
@@ -278,7 +264,7 @@ int crypt_hmac_final(struct crypt_hmac *ctx, char *buffer, size_t length)
|
||||
if (PK11_DigestFinal(ctx->md, tmp, &tmp_len, length) != SECSuccess)
|
||||
return -EINVAL;
|
||||
|
||||
memcpy(buffer, tmp, length);
|
||||
crypt_backend_memcpy(buffer, tmp, length);
|
||||
crypt_backend_memzero(tmp, sizeof(tmp));
|
||||
|
||||
if (tmp_len < length)
|
||||
|
||||
@@ -1,36 +1,15 @@
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later WITH cryptsetup-OpenSSL-exception
|
||||
/*
|
||||
* OPENSSL crypto backend implementation
|
||||
*
|
||||
* Copyright (C) 2010-2023 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2023 Milan Broz
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* In addition, as a special exception, the copyright holders give
|
||||
* permission to link the code of portions of this program with the
|
||||
* OpenSSL library under certain conditions as described in each
|
||||
* individual source file, and distribute linked combinations
|
||||
* including the two.
|
||||
*
|
||||
* You must obey the GNU Lesser General Public License in all respects
|
||||
* for all of the code used other than OpenSSL.
|
||||
* Copyright (C) 2010-2025 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2025 Milan Broz
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <strings.h>
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/hmac.h>
|
||||
@@ -40,6 +19,7 @@
|
||||
#include <openssl/provider.h>
|
||||
#include <openssl/kdf.h>
|
||||
#include <openssl/core_names.h>
|
||||
#include <openssl/err.h>
|
||||
static OSSL_PROVIDER *ossl_legacy = NULL;
|
||||
static OSSL_PROVIDER *ossl_default = NULL;
|
||||
static OSSL_LIB_CTX *ossl_ctx = NULL;
|
||||
@@ -197,12 +177,13 @@ static int openssl_backend_init(bool fips)
|
||||
OSSL_get_max_threads(ossl_ctx) == MAX_THREADS)
|
||||
ossl_threads = true;
|
||||
|
||||
r = snprintf(backend_version, sizeof(backend_version), "%s%s%s%s%s",
|
||||
r = snprintf(backend_version, sizeof(backend_version), "%s %s%s%s%s%s",
|
||||
OpenSSL_version(OPENSSL_VERSION),
|
||||
ossl_default ? "[default]" : "",
|
||||
ossl_legacy ? "[legacy]" : "",
|
||||
fips ? "[fips]" : "",
|
||||
ossl_threads ? "[threads]" : "");
|
||||
ossl_threads ? "[threads]" : "",
|
||||
crypt_backend_flags() & CRYPT_BACKEND_ARGON2 ? "[argon2]" : "");
|
||||
|
||||
if (r < 0 || (size_t)r >= sizeof(backend_version)) {
|
||||
openssl_backend_exit();
|
||||
@@ -224,12 +205,12 @@ static const char *openssl_backend_version(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
int crypt_backend_init(bool fips)
|
||||
int crypt_backend_init(void)
|
||||
{
|
||||
if (crypto_backend_initialised)
|
||||
return 0;
|
||||
|
||||
if (openssl_backend_init(fips))
|
||||
if (openssl_backend_init(crypt_fips_mode()))
|
||||
return -EINVAL;
|
||||
|
||||
crypto_backend_initialised = 1;
|
||||
@@ -251,11 +232,14 @@ void crypt_backend_destroy(void)
|
||||
|
||||
uint32_t crypt_backend_flags(void)
|
||||
{
|
||||
#if OPENSSL_VERSION_MAJOR >= 3
|
||||
return 0;
|
||||
#else
|
||||
return CRYPT_BACKEND_PBKDF2_INT;
|
||||
uint32_t flags = 0;
|
||||
#if OPENSSL_VERSION_MAJOR < 3
|
||||
flags |= CRYPT_BACKEND_PBKDF2_INT;
|
||||
#endif
|
||||
#if HAVE_DECL_OSSL_KDF_PARAM_ARGON2_VERSION
|
||||
flags |= CRYPT_BACKEND_ARGON2;
|
||||
#endif
|
||||
return flags;
|
||||
}
|
||||
|
||||
const char *crypt_backend_version(void)
|
||||
@@ -398,7 +382,7 @@ int crypt_hash_final(struct crypt_hash *ctx, char *buffer, size_t length)
|
||||
if (EVP_DigestFinal_ex(ctx->md, tmp, &tmp_len) != 1)
|
||||
return -EINVAL;
|
||||
|
||||
memcpy(buffer, tmp, length);
|
||||
crypt_backend_memcpy(buffer, tmp, length);
|
||||
crypt_backend_memzero(tmp, sizeof(tmp));
|
||||
|
||||
if (tmp_len < length)
|
||||
@@ -527,7 +511,7 @@ int crypt_hmac_final(struct crypt_hmac *ctx, char *buffer, size_t length)
|
||||
|
||||
HMAC_Final(ctx->md, tmp, &tmp_len);
|
||||
#endif
|
||||
memcpy(buffer, tmp, length);
|
||||
crypt_backend_memcpy(buffer, tmp, length);
|
||||
crypt_backend_memzero(tmp, sizeof(tmp));
|
||||
|
||||
if (tmp_len < length)
|
||||
@@ -641,7 +625,7 @@ static int openssl_argon2(const char *type, const char *password, size_t passwor
|
||||
ctx = EVP_KDF_CTX_new(argon2);
|
||||
if (!ctx) {
|
||||
EVP_KDF_free(argon2);
|
||||
return -EINVAL;;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (EVP_KDF_CTX_set_params(ctx, params) != 1) {
|
||||
@@ -655,6 +639,10 @@ static int openssl_argon2(const char *type, const char *password, size_t passwor
|
||||
EVP_KDF_CTX_free(ctx);
|
||||
EVP_KDF_free(argon2);
|
||||
|
||||
/* Memory allocation is common issue with memory-hard Argon2 */
|
||||
if (r == 0 && ERR_GET_REASON(ERR_get_error()) == ERR_R_MALLOC_FAILURE)
|
||||
return -ENOMEM;
|
||||
|
||||
/* _derive() returns 0 or negative value on error, 1 on success */
|
||||
return r == 1 ? 0 : -EINVAL;
|
||||
#else
|
||||
|
||||
@@ -1,31 +1,21 @@
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
/*
|
||||
* Generic wrapper for storage encryption modes and Initial Vectors
|
||||
* (reimplementation of some functions from Linux dm-crypt kernel)
|
||||
*
|
||||
* Copyright (C) 2014-2023 Milan Broz
|
||||
*
|
||||
* 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.
|
||||
* Copyright (C) 2014-2025 Milan Broz
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <strings.h>
|
||||
#include "bitops.h"
|
||||
#include "crypto_backend.h"
|
||||
|
||||
#define SECTOR_SHIFT 9
|
||||
#define SECTOR_SHIFT 9
|
||||
#define MAX_CAPI_LEN 64
|
||||
#define MAX_CAPI_LEN_STR "63"
|
||||
|
||||
/*
|
||||
* Internal IV helper
|
||||
@@ -225,43 +215,56 @@ int crypt_storage_init(struct crypt_storage **ctx,
|
||||
bool large_iv)
|
||||
{
|
||||
struct crypt_storage *s;
|
||||
char mode_name[64];
|
||||
char cipher_name[MAX_CAPI_LEN], mode_name[MAX_CAPI_LEN], mode_tmp[MAX_CAPI_LEN];
|
||||
char *cipher_iv = NULL;
|
||||
int r = -EIO;
|
||||
int r;
|
||||
|
||||
if (sector_size < (1 << SECTOR_SHIFT) ||
|
||||
sector_size > (1 << (SECTOR_SHIFT + 3)) ||
|
||||
sector_size & (sector_size - 1))
|
||||
return -EINVAL;
|
||||
|
||||
s = malloc(sizeof(*s));
|
||||
if (!s)
|
||||
return -ENOMEM;
|
||||
memset(s, 0, sizeof(*s));
|
||||
/* Convert from capi mode */
|
||||
if (!strncmp(cipher, "capi:", 5)) {
|
||||
r = sscanf(cipher, "capi:%" MAX_CAPI_LEN_STR "[^(](%" MAX_CAPI_LEN_STR "[^)])", mode_tmp, cipher_name);
|
||||
if (r != 2)
|
||||
return -EINVAL;
|
||||
r = snprintf(mode_name, sizeof(mode_name), "%s-%s", mode_tmp, cipher_mode);
|
||||
if (r < 0 || (size_t)r >= sizeof(mode_name))
|
||||
return -EINVAL;
|
||||
} else {
|
||||
strncpy(cipher_name, cipher, sizeof(cipher_name));
|
||||
cipher_name[sizeof(cipher_name) - 1] = 0;
|
||||
strncpy(mode_name, cipher_mode, sizeof(mode_name));
|
||||
mode_name[sizeof(mode_name) - 1] = 0;
|
||||
}
|
||||
|
||||
/* Remove IV if present */
|
||||
strncpy(mode_name, cipher_mode, sizeof(mode_name));
|
||||
mode_name[sizeof(mode_name) - 1] = 0;
|
||||
cipher_iv = strchr(mode_name, '-');
|
||||
if (cipher_iv) {
|
||||
*cipher_iv = '\0';
|
||||
cipher_iv++;
|
||||
}
|
||||
|
||||
r = crypt_cipher_init(&s->cipher, cipher, mode_name, key, key_length);
|
||||
s = malloc(sizeof(*s));
|
||||
if (!s)
|
||||
return -ENOMEM;
|
||||
memset(s, 0, sizeof(*s));
|
||||
|
||||
r = crypt_cipher_init(&s->cipher, cipher_name, mode_name, key, key_length);
|
||||
if (r) {
|
||||
crypt_storage_destroy(s);
|
||||
return r;
|
||||
}
|
||||
|
||||
r = crypt_sector_iv_init(&s->cipher_iv, cipher, mode_name, cipher_iv, key, key_length, sector_size);
|
||||
r = crypt_sector_iv_init(&s->cipher_iv, cipher_name, mode_name, cipher_iv, key, key_length, sector_size);
|
||||
if (r) {
|
||||
crypt_storage_destroy(s);
|
||||
return r;
|
||||
}
|
||||
|
||||
s->sector_size = sector_size;
|
||||
s->iv_shift = large_iv ? int_log2(sector_size) - SECTOR_SHIFT : 0;
|
||||
s->iv_shift = large_iv ? (unsigned)int_log2(sector_size) - SECTOR_SHIFT : 0;
|
||||
|
||||
*ctx = s;
|
||||
return 0;
|
||||
|
||||
61
lib/crypto_backend/memutils.c
Normal file
61
lib/crypto_backend/memutils.c
Normal file
@@ -0,0 +1,61 @@
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
/*
|
||||
* Safe memory utilities
|
||||
*
|
||||
* Copyright (C) 2024-2025 Milan Broz
|
||||
*/
|
||||
|
||||
#include "crypto_backend_internal.h"
|
||||
|
||||
#define ATTR_NOINLINE __attribute__ ((noinline))
|
||||
#define ATTR_ZERO_REGS
|
||||
#if HAVE_ATTRIBUTE_ZEROCALLUSEDREGS
|
||||
# undef ATTR_ZERO_REGS
|
||||
# define ATTR_ZERO_REGS __attribute__ ((zero_call_used_regs("used")))
|
||||
#endif
|
||||
|
||||
/* Workaround for https://github.com/google/sanitizers/issues/1507 */
|
||||
#if defined __has_feature
|
||||
# if __has_feature (memory_sanitizer)
|
||||
# undef HAVE_EXPLICIT_BZERO
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Memzero helper (memset on stack can be optimized out) */
|
||||
ATTR_NOINLINE ATTR_ZERO_REGS
|
||||
void crypt_backend_memzero(void *s, size_t n)
|
||||
{
|
||||
#if HAVE_EXPLICIT_BZERO
|
||||
explicit_bzero(s, n);
|
||||
#else
|
||||
volatile uint8_t *p = (volatile uint8_t *)s;
|
||||
while(n--) *p++ = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Memcpy helper to avoid spilling sensitive data through additional registers */
|
||||
ATTR_NOINLINE ATTR_ZERO_REGS
|
||||
void *crypt_backend_memcpy(void *dst, const void *src, size_t n)
|
||||
{
|
||||
volatile uint8_t *d = (volatile uint8_t *)dst;
|
||||
const volatile uint8_t *s = (const volatile uint8_t *)src;
|
||||
|
||||
while(n--) *d++ = *s++;
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
/* Internal implementation for constant time memory comparison */
|
||||
ATTR_NOINLINE ATTR_ZERO_REGS
|
||||
int crypt_internal_memeq(const void *m1, const void *m2, size_t n)
|
||||
{
|
||||
const unsigned char *_m1 = (const unsigned char *) m1;
|
||||
const unsigned char *_m2 = (const unsigned char *) m2;
|
||||
unsigned char result = 0;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
result |= _m1[i] ^ _m2[i];
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -11,6 +11,7 @@ libcrypto_backend_link_with = []
|
||||
libcrypto_backend_sources = files(
|
||||
'argon2_generic.c',
|
||||
'base64.c',
|
||||
'memutils.c',
|
||||
'cipher_check.c',
|
||||
'cipher_generic.c',
|
||||
'crc32.c',
|
||||
|
||||
@@ -1,26 +1,12 @@
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
/*
|
||||
* Implementation of Password-Based Cryptography as per PKCS#5
|
||||
* Copyright (C) 2002,2003 Simon Josefsson
|
||||
* Copyright (C) 2004 Free Software Foundation
|
||||
*
|
||||
* cryptsetup related changes
|
||||
* Copyright (C) 2012-2023 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2023 Milan Broz
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Copyright (C) 2012-2025 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2025 Milan Broz
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
/*
|
||||
* PBKDF performance check
|
||||
* Copyright (C) 2012-2023 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2023 Milan Broz
|
||||
* Copyright (C) 2012-2025 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2025 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
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
@@ -313,6 +300,7 @@ static int crypt_argon2_check(const char *kdf, const char *password,
|
||||
} while (ms < ms_atleast || ms > ms_atmost);
|
||||
out:
|
||||
if (key) {
|
||||
/* Key can be derived from a real provided password */
|
||||
crypt_backend_memzero(key, key_length);
|
||||
free(key);
|
||||
}
|
||||
@@ -394,6 +382,7 @@ static int crypt_pbkdf_check(const char *kdf, const char *hash,
|
||||
}
|
||||
out:
|
||||
if (key) {
|
||||
/* Key can be derived from a real provided password */
|
||||
crypt_backend_memzero(key, key_length);
|
||||
free(key);
|
||||
}
|
||||
@@ -419,6 +408,9 @@ int crypt_pbkdf_perf(const char *kdf, const char *hash,
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (parallel_threads > pbkdf_limits.max_parallel)
|
||||
return -EINVAL;
|
||||
|
||||
min_memory = pbkdf_limits.min_bench_memory;
|
||||
if (min_memory > max_memory_kb)
|
||||
min_memory = max_memory_kb;
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
/*
|
||||
* UTF8/16 helpers, copied and adapted from systemd project.
|
||||
*
|
||||
* Copyright (C) 2010 Lennart Poettering
|
||||
*
|
||||
* cryptsetup related changes
|
||||
* Copyright (C) 2021-2023 Vojtech Trefny
|
||||
* Copyright (C) 2021-2025 Vojtech Trefny
|
||||
|
||||
* Parts of the original systemd implementation are based on the GLIB utf8
|
||||
* validation functions.
|
||||
@@ -12,20 +13,6 @@
|
||||
*
|
||||
* Copyright (C) 1999 Tom Tromey
|
||||
* Copyright (C) 2000 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
@@ -230,6 +217,7 @@ static size_t utf16_encode_unichar(char16_t *out, char32_t c)
|
||||
return 1;
|
||||
|
||||
case 0x10000U ... 0x10ffffU:
|
||||
/* coverity[overflow_const:FALSE] */
|
||||
c -= 0x10000U;
|
||||
out[0] = htole16((c >> 10) + 0xd800U);
|
||||
out[1] = htole16((c & 0x3ffU) + 0xdc00U);
|
||||
@@ -286,3 +274,20 @@ int crypt_utf8_to_utf16(char16_t **out, const char *s, size_t length)
|
||||
*p = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* crypt_char16_strlen()
|
||||
* @s: string to get length of
|
||||
*
|
||||
* Returns: number of 16-bit words in the string
|
||||
*/
|
||||
size_t crypt_char16_strlen(const char16_t *s) {
|
||||
size_t n = 0;
|
||||
|
||||
assert(s);
|
||||
|
||||
while (*s != 0)
|
||||
n++, s++;
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
@@ -1,21 +1,8 @@
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
/*
|
||||
* FVAULT2 (FileVault2-compatible) volume handling
|
||||
*
|
||||
* Copyright (C) 2021-2022 Pavel Tobias
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
@@ -526,6 +513,7 @@ static int _read_volume_header(
|
||||
int r = 0;
|
||||
struct device *dev = crypt_metadata_device(cd);
|
||||
struct volume_header *vol_header = NULL;
|
||||
void *enc_key = NULL;
|
||||
|
||||
assert(sizeof(*vol_header) == FVAULT2_VOL_HEADER_SIZE);
|
||||
|
||||
@@ -570,8 +558,8 @@ static int _read_volume_header(
|
||||
goto out;
|
||||
}
|
||||
|
||||
*enc_md_key = crypt_alloc_volume_key(FVAULT2_XTS_KEY_SIZE, NULL);
|
||||
if (*enc_md_key == NULL) {
|
||||
enc_key = crypt_safe_alloc(FVAULT2_XTS_KEY_SIZE);
|
||||
if (!enc_key) {
|
||||
r = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
@@ -579,9 +567,15 @@ static int _read_volume_header(
|
||||
*block_size = le32_to_cpu(vol_header->block_size);
|
||||
*disklbl_blkoff = le64_to_cpu(vol_header->disklbl_blkoff);
|
||||
uuid_unparse(vol_header->ph_vol_uuid, ph_vol_uuid);
|
||||
memcpy((*enc_md_key)->key, vol_header->key_data, FVAULT2_AES_KEY_SIZE);
|
||||
memcpy((*enc_md_key)->key + FVAULT2_AES_KEY_SIZE,
|
||||
crypt_safe_memcpy(enc_key, vol_header->key_data, FVAULT2_AES_KEY_SIZE);
|
||||
crypt_safe_memcpy((char *)enc_key + FVAULT2_AES_KEY_SIZE,
|
||||
vol_header->ph_vol_uuid, FVAULT2_AES_KEY_SIZE);
|
||||
|
||||
*enc_md_key = crypt_alloc_volume_key_by_safe_alloc(&enc_key);
|
||||
if (*enc_md_key == NULL) {
|
||||
crypt_safe_free(enc_key);
|
||||
r = -ENOMEM;
|
||||
}
|
||||
out:
|
||||
free(vol_header);
|
||||
return r;
|
||||
@@ -717,7 +711,7 @@ static int _read_encrypted_metadata(
|
||||
goto out;
|
||||
}
|
||||
|
||||
r = crypt_cipher_init(&cipher, "aes", "xts", key->key, FVAULT2_XTS_KEY_SIZE);
|
||||
r = crypt_cipher_init(&cipher, "aes", "xts", crypt_volume_key_get_key(key), FVAULT2_XTS_KEY_SIZE);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
|
||||
@@ -848,8 +842,7 @@ static int _activate(
|
||||
r = dm_crypt_target_set(&dm_dev.segment, 0, dm_dev.size,
|
||||
crypt_data_device(cd), vol_key, cipher,
|
||||
crypt_get_iv_offset(cd), crypt_get_data_offset(cd),
|
||||
crypt_get_integrity(cd), crypt_get_integrity_tag_size(cd),
|
||||
crypt_get_sector_size(cd));
|
||||
NULL, 0, 0, crypt_get_sector_size(cd));
|
||||
|
||||
if (!r)
|
||||
r = dm_create_device(cd, name, CRYPT_FVAULT2, &dm_dev);
|
||||
@@ -906,15 +899,14 @@ int FVAULT2_get_volume_key(
|
||||
const char *passphrase,
|
||||
size_t passphrase_len,
|
||||
const struct fvault2_params *params,
|
||||
struct volume_key **vol_key)
|
||||
struct volume_key **r_vol_key)
|
||||
{
|
||||
int r = 0;
|
||||
uint8_t family_uuid_bin[FVAULT2_UUID_BIN_SIZE];
|
||||
struct volume_key *passphrase_key = NULL;
|
||||
struct volume_key *kek = NULL;
|
||||
struct crypt_hash *hash = NULL;
|
||||
void *passphrase_key = NULL, *kek = NULL, *vol_key= NULL;
|
||||
|
||||
*vol_key = NULL;
|
||||
*r_vol_key = NULL;
|
||||
|
||||
if (uuid_parse(params->family_uuid, family_uuid_bin) < 0) {
|
||||
log_dbg(cd, "Could not parse logical volume family UUID: %s.",
|
||||
@@ -923,61 +915,62 @@ int FVAULT2_get_volume_key(
|
||||
goto out;
|
||||
}
|
||||
|
||||
passphrase_key = crypt_alloc_volume_key(FVAULT2_AES_KEY_SIZE, NULL);
|
||||
passphrase_key = crypt_safe_alloc(FVAULT2_AES_KEY_SIZE);
|
||||
if (passphrase_key == NULL) {
|
||||
r = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
r = crypt_pbkdf("pbkdf2", "sha256", passphrase, passphrase_len,
|
||||
params->pbkdf2_salt, FVAULT2_PBKDF2_SALT_SIZE, passphrase_key->key,
|
||||
params->pbkdf2_salt, FVAULT2_PBKDF2_SALT_SIZE, passphrase_key,
|
||||
FVAULT2_AES_KEY_SIZE, params->pbkdf2_iters, 0, 0);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
|
||||
kek = crypt_alloc_volume_key(FVAULT2_AES_KEY_SIZE, NULL);
|
||||
kek = crypt_safe_alloc(FVAULT2_AES_KEY_SIZE);
|
||||
if (kek == NULL) {
|
||||
r = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
r = _unwrap_key(passphrase_key->key, FVAULT2_AES_KEY_SIZE, params->wrapped_kek,
|
||||
FVAULT2_WRAPPED_KEY_SIZE, kek->key, FVAULT2_AES_KEY_SIZE);
|
||||
r = _unwrap_key(passphrase_key, FVAULT2_AES_KEY_SIZE, params->wrapped_kek,
|
||||
FVAULT2_WRAPPED_KEY_SIZE, kek, FVAULT2_AES_KEY_SIZE);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
|
||||
*vol_key = crypt_alloc_volume_key(FVAULT2_XTS_KEY_SIZE, NULL);
|
||||
if (*vol_key == NULL) {
|
||||
vol_key = crypt_safe_alloc(FVAULT2_XTS_KEY_SIZE);
|
||||
if (vol_key == NULL) {
|
||||
r = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
r = _unwrap_key(kek->key, FVAULT2_AES_KEY_SIZE, params->wrapped_vk,
|
||||
FVAULT2_WRAPPED_KEY_SIZE, (*vol_key)->key, FVAULT2_AES_KEY_SIZE);
|
||||
r = _unwrap_key(kek, FVAULT2_AES_KEY_SIZE, params->wrapped_vk,
|
||||
FVAULT2_WRAPPED_KEY_SIZE, vol_key, FVAULT2_AES_KEY_SIZE);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
|
||||
r = crypt_hash_init(&hash, "sha256");
|
||||
if (r < 0)
|
||||
goto out;
|
||||
r = crypt_hash_write(hash, (*vol_key)->key, FVAULT2_AES_KEY_SIZE);
|
||||
r = crypt_hash_write(hash, vol_key, FVAULT2_AES_KEY_SIZE);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
r = crypt_hash_write(hash, (char *)family_uuid_bin,
|
||||
FVAULT2_UUID_BIN_SIZE);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
r = crypt_hash_final(hash, (*vol_key)->key + FVAULT2_AES_KEY_SIZE,
|
||||
r = crypt_hash_final(hash, (char *)vol_key + FVAULT2_AES_KEY_SIZE,
|
||||
FVAULT2_AES_KEY_SIZE);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
|
||||
*r_vol_key = crypt_alloc_volume_key_by_safe_alloc(&vol_key);
|
||||
if (!*r_vol_key)
|
||||
r = -ENOMEM;
|
||||
out:
|
||||
crypt_free_volume_key(passphrase_key);
|
||||
crypt_free_volume_key(kek);
|
||||
if (r < 0) {
|
||||
crypt_free_volume_key(*vol_key);
|
||||
*vol_key = NULL;
|
||||
}
|
||||
crypt_safe_free(passphrase_key);
|
||||
crypt_safe_free(kek);
|
||||
crypt_safe_free(vol_key);
|
||||
if (hash != NULL)
|
||||
crypt_hash_destroy(hash);
|
||||
return r;
|
||||
@@ -1010,48 +1003,19 @@ int FVAULT2_dump(
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FVAULT2_activate_by_passphrase(
|
||||
struct crypt_device *cd,
|
||||
const char *name,
|
||||
const char *passphrase,
|
||||
size_t passphrase_len,
|
||||
const struct fvault2_params *params,
|
||||
uint32_t flags)
|
||||
{
|
||||
int r;
|
||||
struct volume_key *vol_key = NULL;
|
||||
|
||||
r = FVAULT2_get_volume_key(cd, passphrase, passphrase_len, params, &vol_key);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (name)
|
||||
r = _activate(cd, name, vol_key, params, flags);
|
||||
|
||||
crypt_free_volume_key(vol_key);
|
||||
return r;
|
||||
}
|
||||
|
||||
int FVAULT2_activate_by_volume_key(
|
||||
struct crypt_device *cd,
|
||||
const char *name,
|
||||
const char *key,
|
||||
size_t key_size,
|
||||
struct volume_key *vk,
|
||||
const struct fvault2_params *params,
|
||||
uint32_t flags)
|
||||
{
|
||||
int r = 0;
|
||||
struct volume_key *vol_key = NULL;
|
||||
assert(crypt_volume_key_length(vk) == FVAULT2_XTS_KEY_SIZE);
|
||||
|
||||
if (key_size != FVAULT2_XTS_KEY_SIZE)
|
||||
return -EINVAL;
|
||||
|
||||
vol_key = crypt_alloc_volume_key(FVAULT2_XTS_KEY_SIZE, key);
|
||||
if (vol_key == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
r = _activate(cd, name, vol_key, params, flags);
|
||||
|
||||
crypt_free_volume_key(vol_key);
|
||||
return r;
|
||||
return _activate(cd, name, vk, params, flags);
|
||||
}
|
||||
|
||||
size_t FVAULT2_volume_key_size(void)
|
||||
{
|
||||
return FVAULT2_XTS_KEY_SIZE;
|
||||
}
|
||||
|
||||
@@ -1,21 +1,8 @@
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
/*
|
||||
* FVAULT2 (FileVault2-compatible) volume handling
|
||||
*
|
||||
* Copyright (C) 2021-2022 Pavel Tobias
|
||||
*
|
||||
* 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_FVAULT2_H
|
||||
@@ -54,27 +41,20 @@ int FVAULT2_get_volume_key(
|
||||
const char *passphrase,
|
||||
size_t passphrase_len,
|
||||
const struct fvault2_params *params,
|
||||
struct volume_key **vol_key);
|
||||
struct volume_key **r_vol_key);
|
||||
|
||||
int FVAULT2_dump(
|
||||
struct crypt_device *cd,
|
||||
struct device *device,
|
||||
const struct fvault2_params *params);
|
||||
|
||||
int FVAULT2_activate_by_passphrase(
|
||||
struct crypt_device *cd,
|
||||
const char *name,
|
||||
const char *passphrase,
|
||||
size_t passphrase_len,
|
||||
const struct fvault2_params *params,
|
||||
uint32_t flags);
|
||||
|
||||
int FVAULT2_activate_by_volume_key(
|
||||
struct crypt_device *cd,
|
||||
const char *name,
|
||||
const char *key,
|
||||
size_t key_size,
|
||||
struct volume_key *vk,
|
||||
const struct fvault2_params *params,
|
||||
uint32_t flags);
|
||||
|
||||
size_t FVAULT2_volume_key_size(void);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,21 +1,8 @@
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
/*
|
||||
* Integrity volume handling
|
||||
*
|
||||
* Copyright (C) 2016-2023 Milan Broz
|
||||
*
|
||||
* 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.
|
||||
* Copyright (C) 2016-2025 Milan Broz
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
@@ -44,16 +31,22 @@ static int INTEGRITY_read_superblock(struct crypt_device *cd,
|
||||
{
|
||||
int devfd, r;
|
||||
|
||||
log_dbg(cd, "Reading kernel dm-integrity metadata on %s.", device_path(device));
|
||||
|
||||
devfd = device_open(cd, device, O_RDONLY);
|
||||
if(devfd < 0)
|
||||
return -EINVAL;
|
||||
|
||||
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))) {
|
||||
device_alignment(device), sb, sizeof(*sb), offset) != sizeof(*sb)) {
|
||||
log_dbg(cd, "Cannot read kernel dm-integrity metadata on %s.", device_path(device));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (memcmp(sb->magic, SB_MAGIC, sizeof(sb->magic))) {
|
||||
log_dbg(cd, "No kernel dm-integrity metadata detected on %s.", device_path(device));
|
||||
r = -EINVAL;
|
||||
} else if (sb->version < SB_VERSION_1 || sb->version > SB_VERSION_5) {
|
||||
} else if (sb->version < SB_VERSION_1 || sb->version > SB_VERSION_6) {
|
||||
log_err(cd, _("Incompatible kernel dm-integrity metadata (version %u) detected on %s."),
|
||||
sb->version, device_path(device));
|
||||
r = -EINVAL;
|
||||
@@ -80,8 +73,10 @@ int INTEGRITY_read_sb(struct crypt_device *cd,
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
params->sector_size = SECTOR_SIZE << sb.log2_sectors_per_block;
|
||||
params->tag_size = sb.integrity_tag_size;
|
||||
if (params) {
|
||||
params->sector_size = SECTOR_SIZE << sb.log2_sectors_per_block;
|
||||
params->tag_size = sb.integrity_tag_size;
|
||||
}
|
||||
|
||||
if (flags)
|
||||
*flags = sb.flags;
|
||||
@@ -92,28 +87,32 @@ int INTEGRITY_read_sb(struct crypt_device *cd,
|
||||
int INTEGRITY_dump(struct crypt_device *cd, struct device *device, uint64_t offset)
|
||||
{
|
||||
struct superblock sb;
|
||||
uint64_t sector_size;
|
||||
int r;
|
||||
|
||||
r = INTEGRITY_read_superblock(cd, device, offset, &sb);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
log_std(cd, "Info for integrity device %s.\n", device_path(device));
|
||||
log_std(cd, "superblock_version %d\n", (unsigned)sb.version);
|
||||
log_std(cd, "log2_interleave_sectors %d\n", sb.log2_interleave_sectors);
|
||||
log_std(cd, "integrity_tag_size %u\n", sb.integrity_tag_size);
|
||||
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);
|
||||
sector_size = (uint64_t)SECTOR_SIZE << sb.log2_sectors_per_block;
|
||||
log_std(cd, "INTEGRITY header information for %s.\n", device_path(device));
|
||||
log_std(cd, "version: %d\n", (unsigned)sb.version);
|
||||
log_std(cd, "tag size: %u [bytes]\n", sb.integrity_tag_size);
|
||||
log_std(cd, "sector size: %" PRIu64 " [bytes]\n", sector_size);
|
||||
log_std(cd, "data size: %" PRIu64 " [512-byte units] (%" PRIu64 " [bytes])\n",
|
||||
sb.provided_data_sectors, sb.provided_data_sectors * SECTOR_SIZE);
|
||||
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%s%s\n",
|
||||
log_std(cd, "recalculate sector: %" PRIu64 "\n", sb.recalc_sector);
|
||||
log_std(cd, "journal sections: %u\n", sb.journal_sections);
|
||||
log_std(cd, "log2 interleave sectors: %d\n", sb.log2_interleave_sectors);
|
||||
log_std(cd, "log2 blocks per bitmap: %u\n", sb.log2_blocks_per_bitmap_bit);
|
||||
log_std(cd, "flags: %s%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_FIXED_PADDING ? "fix_padding " : "",
|
||||
sb.flags & SB_FLAG_FIXED_HMAC ? "fix_hmac " : "");
|
||||
sb.flags & SB_FLAG_FIXED_HMAC ? "fix_hmac " : "",
|
||||
sb.flags & SB_FLAG_INLINE ? "inline " : "");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -133,26 +132,42 @@ int INTEGRITY_data_sectors(struct crypt_device *cd,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int INTEGRITY_key_size(const char *integrity)
|
||||
int INTEGRITY_key_size(const char *integrity, int required_key_size)
|
||||
{
|
||||
int ks = 0;
|
||||
|
||||
if (!integrity && required_key_size)
|
||||
return -EINVAL;
|
||||
|
||||
if (!integrity)
|
||||
return 0;
|
||||
|
||||
//FIXME: use crypto backend hash size
|
||||
if (!strcmp(integrity, "aead"))
|
||||
return 0;
|
||||
ks = 0;
|
||||
else if (!strcmp(integrity, "hmac(sha1)"))
|
||||
return 20;
|
||||
ks = required_key_size ?: 20;
|
||||
else if (!strcmp(integrity, "hmac(sha256)"))
|
||||
return 32;
|
||||
ks = required_key_size ?: 32;
|
||||
else if (!strcmp(integrity, "hmac(sha512)"))
|
||||
return 64;
|
||||
ks = required_key_size ?: 64;
|
||||
else if (!strcmp(integrity, "phmac(sha1)"))
|
||||
ks = required_key_size ?: -EINVAL;
|
||||
else if (!strcmp(integrity, "phmac(sha256)"))
|
||||
ks = required_key_size ?: -EINVAL;
|
||||
else if (!strcmp(integrity, "phmac(sha512)"))
|
||||
ks = required_key_size ?: -EINVAL;
|
||||
else if (!strcmp(integrity, "poly1305"))
|
||||
return 0;
|
||||
ks = 0;
|
||||
else if (!strcmp(integrity, "none"))
|
||||
return 0;
|
||||
ks = 0;
|
||||
else
|
||||
return -EINVAL;
|
||||
|
||||
return -EINVAL;
|
||||
if (required_key_size && ks != required_key_size)
|
||||
return -EINVAL;
|
||||
|
||||
return ks;
|
||||
}
|
||||
|
||||
/* Return hash or hmac(hash) size, if known */
|
||||
@@ -171,6 +186,8 @@ int INTEGRITY_hash_tag_size(const char *integrity)
|
||||
return 8;
|
||||
|
||||
r = sscanf(integrity, "hmac(%" MAX_CIPHER_LEN_STR "[^)]s", hash);
|
||||
if (r != 1)
|
||||
r = sscanf(integrity, "phmac(%" MAX_CIPHER_LEN_STR "[^)]s", hash);
|
||||
if (r == 1)
|
||||
r = crypt_hash_size(hash);
|
||||
else
|
||||
@@ -213,6 +230,12 @@ int INTEGRITY_tag_size(const char *integrity,
|
||||
auth_tag_size = 32;
|
||||
else if (!strcmp(integrity, "hmac(sha512)"))
|
||||
auth_tag_size = 64;
|
||||
else if (!strcmp(integrity, "phmac(sha1)"))
|
||||
auth_tag_size = 20;
|
||||
else if (!strcmp(integrity, "phmac(sha256)"))
|
||||
auth_tag_size = 32;
|
||||
else if (!strcmp(integrity, "phmac(sha512)"))
|
||||
auth_tag_size = 64;
|
||||
else if (!strcmp(integrity, "poly1305")) {
|
||||
if (iv_tag_size)
|
||||
iv_tag_size = 12;
|
||||
@@ -243,6 +266,9 @@ int INTEGRITY_create_dmd_device(struct crypt_device *cd,
|
||||
if (sb_flags & SB_FLAG_RECALCULATING)
|
||||
dmd->flags |= CRYPT_ACTIVATE_RECALCULATE;
|
||||
|
||||
if (sb_flags & SB_FLAG_INLINE)
|
||||
dmd->flags |= (CRYPT_ACTIVATE_NO_JOURNAL | CRYPT_ACTIVATE_INLINE_MODE);
|
||||
|
||||
r = INTEGRITY_data_sectors(cd, INTEGRITY_metadata_device(cd),
|
||||
crypt_get_data_offset(cd) * SECTOR_SIZE, &dmd->size);
|
||||
if (r < 0)
|
||||
@@ -262,14 +288,15 @@ int INTEGRITY_activate_dmd_device(struct crypt_device *cd,
|
||||
uint32_t sb_flags)
|
||||
{
|
||||
int r;
|
||||
uint32_t dmi_flags;
|
||||
uint64_t dmi_flags;
|
||||
struct dm_target *tgt = &dmd->segment;
|
||||
|
||||
if (!single_segment(dmd) || tgt->type != DM_INTEGRITY)
|
||||
return -EINVAL;
|
||||
|
||||
log_dbg(cd, "Trying to activate INTEGRITY device on top of %s, using name %s, tag size %d, provided sectors %" PRIu64".",
|
||||
device_path(tgt->data_device), name, tgt->u.integrity.tag_size, dmd->size);
|
||||
log_dbg(cd, "Trying to activate INTEGRITY device on top of %s, using name %s, tag size %d%s, provided sectors %" PRIu64".",
|
||||
device_path(tgt->data_device), name, tgt->u.integrity.tag_size,
|
||||
(sb_flags & SB_FLAG_INLINE) ? " (inline)" :"", dmd->size);
|
||||
|
||||
r = create_or_reload_device(cd, name, type, dmd);
|
||||
|
||||
@@ -293,6 +320,12 @@ int INTEGRITY_activate_dmd_device(struct crypt_device *cd,
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
if (r < 0 && (sb_flags & SB_FLAG_INLINE) && !dm_flags(cd, DM_INTEGRITY, &dmi_flags) &&
|
||||
!(dmi_flags & DM_INTEGRITY_INLINE_MODE_SUPPORTED)) {
|
||||
log_err(cd, _("Kernel does not support dm-integrity inline mode."));
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -385,11 +418,14 @@ static int _create_reduced_device(struct crypt_device *cd,
|
||||
|
||||
int INTEGRITY_format(struct crypt_device *cd,
|
||||
const struct crypt_params_integrity *params,
|
||||
struct volume_key *integrity_key,
|
||||
struct volume_key *journal_crypt_key,
|
||||
struct volume_key *journal_mac_key,
|
||||
uint64_t backing_device_sectors)
|
||||
uint64_t backing_device_sectors,
|
||||
uint32_t *sb_flags,
|
||||
bool integrity_inline)
|
||||
{
|
||||
uint32_t dmi_flags;
|
||||
uint64_t dmi_flags;
|
||||
char reduced_device_name[70], tmp_name[64], tmp_uuid[40];
|
||||
struct crypt_dm_active_device dmdi = {
|
||||
.size = 8,
|
||||
@@ -400,7 +436,6 @@ int INTEGRITY_format(struct crypt_device *cd,
|
||||
uuid_t tmp_uuid_bin;
|
||||
uint64_t data_offset_sectors;
|
||||
struct device *p_metadata_device, *p_data_device, *reduced_device = NULL;
|
||||
struct volume_key *vk = NULL;
|
||||
|
||||
uuid_generate(tmp_uuid_bin);
|
||||
uuid_unparse(tmp_uuid_bin, tmp_uuid);
|
||||
@@ -435,19 +470,18 @@ int INTEGRITY_format(struct crypt_device *cd,
|
||||
p_data_device = crypt_data_device(cd);
|
||||
}
|
||||
|
||||
/* There is no data area, we can actually use fake zeroed key */
|
||||
if (params && params->integrity_key_size)
|
||||
vk = crypt_alloc_volume_key(params->integrity_key_size, NULL);
|
||||
if (integrity_inline)
|
||||
dmdi.flags |= (CRYPT_ACTIVATE_NO_JOURNAL | CRYPT_ACTIVATE_INLINE_MODE);
|
||||
|
||||
r = dm_integrity_target_set(cd, tgt, 0, dmdi.size, p_metadata_device,
|
||||
p_data_device, crypt_get_integrity_tag_size(cd),
|
||||
data_offset_sectors, crypt_get_sector_size(cd), vk,
|
||||
data_offset_sectors, crypt_get_sector_size(cd), integrity_key,
|
||||
journal_crypt_key, journal_mac_key, params);
|
||||
if (r < 0)
|
||||
goto err;
|
||||
|
||||
log_dbg(cd, "Trying to format INTEGRITY device on top of %s, tmp name %s, tag size %d.",
|
||||
device_path(tgt->data_device), tmp_name, tgt->u.integrity.tag_size);
|
||||
log_dbg(cd, "Trying to format INTEGRITY device on top of %s, tmp name %s, tag size %d%s.",
|
||||
device_path(tgt->data_device), tmp_name, tgt->u.integrity.tag_size, integrity_inline ? " (inline)" : "");
|
||||
|
||||
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))) {
|
||||
@@ -468,9 +502,14 @@ int INTEGRITY_format(struct crypt_device *cd,
|
||||
goto err;
|
||||
|
||||
r = dm_remove_device(cd, tmp_name, CRYPT_DEACTIVATE_FORCE);
|
||||
if (r)
|
||||
goto err;
|
||||
|
||||
/* reload sb_flags from superblock (important for SB_FLAG_INLINE) */
|
||||
if (sb_flags)
|
||||
r = INTEGRITY_read_sb(cd, NULL, sb_flags);
|
||||
err:
|
||||
dm_targets_free(cd, &dmdi);
|
||||
crypt_free_volume_key(vk);
|
||||
if (reduced_device) {
|
||||
dm_remove_device(cd, reduced_device_name, CRYPT_DEACTIVATE_FORCE);
|
||||
device_free(cd, reduced_device);
|
||||
|
||||
@@ -1,27 +1,15 @@
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
/*
|
||||
* Integrity header definition
|
||||
*
|
||||
* Copyright (C) 2016-2023 Milan Broz
|
||||
*
|
||||
* 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.
|
||||
* Copyright (C) 2016-2025 Milan Broz
|
||||
*/
|
||||
|
||||
#ifndef _CRYPTSETUP_INTEGRITY_H
|
||||
#define _CRYPTSETUP_INTEGRITY_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
struct crypt_device;
|
||||
struct device;
|
||||
@@ -36,12 +24,14 @@ struct crypt_dm_active_device;
|
||||
#define SB_VERSION_3 3
|
||||
#define SB_VERSION_4 4
|
||||
#define SB_VERSION_5 5
|
||||
#define SB_VERSION_6 6
|
||||
|
||||
#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 */
|
||||
#define SB_FLAG_INLINE (1 << 5) /* V6 only */
|
||||
|
||||
struct superblock {
|
||||
uint8_t magic[8];
|
||||
@@ -53,8 +43,10 @@ struct superblock {
|
||||
uint32_t flags;
|
||||
uint8_t log2_sectors_per_block;
|
||||
uint8_t log2_blocks_per_bitmap_bit; /* V3 only */
|
||||
uint8_t pad[2];
|
||||
uint8_t pad[2]; /* (padding) */
|
||||
uint64_t recalc_sector; /* V2 only */
|
||||
uint8_t pad2[8]; /* (padding) */
|
||||
uint8_t salt[16]; /* for fixed hmac, V5 only */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
int INTEGRITY_read_sb(struct crypt_device *cd,
|
||||
@@ -66,7 +58,7 @@ int INTEGRITY_dump(struct crypt_device *cd, struct device *device, uint64_t offs
|
||||
int INTEGRITY_data_sectors(struct crypt_device *cd,
|
||||
struct device *device, uint64_t offset,
|
||||
uint64_t *data_sectors);
|
||||
int INTEGRITY_key_size(const char *integrity);
|
||||
int INTEGRITY_key_size(const char *integrity, int required_key_size);
|
||||
int INTEGRITY_tag_size(const char *integrity,
|
||||
const char *cipher,
|
||||
const char *cipher_mode);
|
||||
@@ -74,9 +66,12 @@ int INTEGRITY_hash_tag_size(const char *integrity);
|
||||
|
||||
int INTEGRITY_format(struct crypt_device *cd,
|
||||
const struct crypt_params_integrity *params,
|
||||
struct volume_key *integrity_key,
|
||||
struct volume_key *journal_crypt_key,
|
||||
struct volume_key *journal_mac_key,
|
||||
uint64_t backing_device_sectors);
|
||||
uint64_t backing_device_sectors,
|
||||
uint32_t *sb_flags,
|
||||
bool integrity_inline);
|
||||
|
||||
int INTEGRITY_activate(struct crypt_device *cd,
|
||||
const char *name,
|
||||
|
||||
@@ -1,24 +1,11 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* libcryptsetup - cryptsetup library internal
|
||||
*
|
||||
* Copyright (C) 2004 Jana Saout <jana@saout.de>
|
||||
* Copyright (C) 2004-2007 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2023 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2023 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* Copyright (C) 2009-2025 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2025 Milan Broz
|
||||
*/
|
||||
|
||||
#ifndef INTERNAL_H
|
||||
@@ -61,24 +48,36 @@
|
||||
|
||||
struct crypt_device;
|
||||
struct luks2_reencrypt;
|
||||
struct volume_key;
|
||||
|
||||
struct volume_key {
|
||||
int id;
|
||||
size_t keylength;
|
||||
const char *key_description;
|
||||
struct volume_key *next;
|
||||
char key[];
|
||||
};
|
||||
typedef enum {
|
||||
KEY_QUALITY_KEY = 0,
|
||||
KEY_QUALITY_NORMAL,
|
||||
KEY_QUALITY_EMPTY
|
||||
} key_quality_info;
|
||||
|
||||
struct volume_key *crypt_alloc_volume_key(size_t keylength, const char *key);
|
||||
struct volume_key *crypt_generate_volume_key(struct crypt_device *cd, size_t keylength);
|
||||
struct volume_key *crypt_alloc_volume_key_by_safe_alloc(void **safe_alloc);
|
||||
struct volume_key *crypt_generate_volume_key(struct crypt_device *cd, size_t keylength,
|
||||
key_quality_info quality);
|
||||
void crypt_free_volume_key(struct volume_key *vk);
|
||||
int crypt_volume_key_set_description(struct volume_key *key, const char *key_description);
|
||||
const char *crypt_volume_key_get_key(const struct volume_key *vk);
|
||||
size_t crypt_volume_key_length(const struct volume_key *vk);
|
||||
int crypt_volume_key_set_description(struct volume_key *key,
|
||||
const char *key_description, key_type_t keyring_key_type);
|
||||
int crypt_volume_key_set_description_by_name(struct volume_key *vk, const char *key_name);
|
||||
key_type_t crypt_volume_key_kernel_key_type(const struct volume_key *vk);
|
||||
const char *crypt_volume_key_description(const struct volume_key *vk);
|
||||
void crypt_volume_key_set_id(struct volume_key *vk, int id);
|
||||
int crypt_volume_key_get_id(const struct volume_key *vk);
|
||||
void crypt_volume_key_add_next(struct volume_key **vks, struct volume_key *vk);
|
||||
struct volume_key *crypt_volume_key_next(struct volume_key *vk);
|
||||
struct volume_key *crypt_volume_key_by_id(struct volume_key *vk, int id);
|
||||
void crypt_volume_key_pass_safe_alloc(struct volume_key *vk, void **safe_alloc);
|
||||
bool crypt_volume_key_is_set(const struct volume_key *vk);
|
||||
bool crypt_volume_key_upload_kernel_key(struct volume_key *vk);
|
||||
void crypt_volume_key_drop_uploaded_kernel_key(struct crypt_device *cd, struct volume_key *vk);
|
||||
void crypt_volume_key_drop_kernel_key(struct crypt_device *cd, struct volume_key *vk);
|
||||
|
||||
struct crypt_pbkdf_type *crypt_get_pbkdf(struct crypt_device *cd);
|
||||
int init_pbkdf_type(struct crypt_device *cd,
|
||||
@@ -99,7 +98,6 @@ int device_alloc_no_check(struct device **device, const char *path);
|
||||
void device_close(struct crypt_device *cd, struct device *device);
|
||||
void device_free(struct crypt_device *cd, struct device *device);
|
||||
const char *device_path(const struct device *device);
|
||||
const char *device_dm_name(const struct device *device);
|
||||
const char *device_block_path(const struct device *device);
|
||||
void device_topology_alignment(struct crypt_device *cd,
|
||||
struct device *device,
|
||||
@@ -116,6 +114,8 @@ void device_disable_direct_io(struct device *device);
|
||||
int device_is_identical(struct device *device1, struct device *device2);
|
||||
int device_is_rotational(struct device *device);
|
||||
int device_is_dax(struct device *device);
|
||||
int device_is_zoned(struct device *device);
|
||||
int device_is_nop_dif(struct device *device, uint32_t *tag_size);
|
||||
size_t device_alignment(struct device *device);
|
||||
int device_direct_io(const struct device *device);
|
||||
int device_fallocate(struct device *device, uint64_t size);
|
||||
@@ -166,6 +166,8 @@ int crypt_confirm(struct crypt_device *cd, const char *msg);
|
||||
char *crypt_lookup_dev(const char *dev_id);
|
||||
int crypt_dev_is_rotational(int major, int minor);
|
||||
int crypt_dev_is_dax(int major, int minor);
|
||||
int crypt_dev_is_zoned(int major, int minor);
|
||||
int crypt_dev_is_nop_dif(int major, int minor, uint32_t *tag_size);
|
||||
int crypt_dev_is_partition(const char *dev_path);
|
||||
char *crypt_get_partition_device(const char *dev_path, uint64_t offset, uint64_t size);
|
||||
int crypt_dev_get_partition_number(const char *dev_path);
|
||||
@@ -173,8 +175,6 @@ char *crypt_get_base_device(const char *dev_path);
|
||||
uint64_t crypt_dev_partition_offset(const char *dev_path);
|
||||
int lookup_by_disk_id(const char *dm_uuid);
|
||||
int lookup_by_sysfs_uuid_field(const char *dm_uuid);
|
||||
int crypt_uuid_cmp(const char *dm_uuid, const char *hdr_uuid);
|
||||
int crypt_uuid_type_cmp(const char *dm_uuid, const char *type);
|
||||
|
||||
size_t crypt_getpagesize(void);
|
||||
unsigned crypt_cpusonline(void);
|
||||
@@ -228,7 +228,7 @@ int crypt_wipe_device(struct crypt_device *cd,
|
||||
|
||||
/* Internal integrity helpers */
|
||||
const char *crypt_get_integrity(struct crypt_device *cd);
|
||||
int crypt_get_integrity_key_size(struct crypt_device *cd);
|
||||
int crypt_get_integrity_key_size(struct crypt_device *cd, bool dm_compat);
|
||||
int crypt_get_integrity_tag_size(struct crypt_device *cd);
|
||||
|
||||
int crypt_key_in_keyring(struct crypt_device *cd);
|
||||
@@ -242,9 +242,18 @@ int crypt_keyring_get_key_by_name(struct crypt_device *cd,
|
||||
const char *key_description,
|
||||
char **key,
|
||||
size_t *key_size);
|
||||
|
||||
int crypt_keyring_get_keysize_by_name(struct crypt_device *cd,
|
||||
const char *key_description,
|
||||
size_t *r_key_size);
|
||||
|
||||
int crypt_use_keyring_for_vk(struct crypt_device *cd);
|
||||
void crypt_drop_keyring_key_by_description(struct crypt_device *cd, const char *key_description, key_type_t ktype);
|
||||
void crypt_drop_keyring_key(struct crypt_device *cd, struct volume_key *vks);
|
||||
void crypt_unlink_key_from_thread_keyring(struct crypt_device *cd,
|
||||
key_serial_t key_id);
|
||||
void crypt_unlink_key_by_description_from_thread_keyring(struct crypt_device *cd,
|
||||
const char *key_description,
|
||||
key_type_t ktype);
|
||||
void crypt_drop_uploaded_keyring_key(struct crypt_device *cd, struct volume_key *vks);
|
||||
|
||||
static inline uint64_t compact_version(uint16_t major, uint16_t minor, uint16_t patch, uint16_t release)
|
||||
{
|
||||
@@ -266,6 +275,8 @@ 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 (size == 0)
|
||||
return true;
|
||||
if ((uint64_t)(*u / size) != b)
|
||||
return true;
|
||||
return false;
|
||||
@@ -275,4 +286,6 @@ static inline bool uint64_mult_overflow(uint64_t *u, uint64_t b, size_t size)
|
||||
#define KEY_EXTERNAL_VERIFICATION -1
|
||||
#define KEY_VERIFIED 0
|
||||
|
||||
size_t crypt_safe_alloc_size(const void *data);
|
||||
|
||||
#endif /* INTERNAL_H */
|
||||
|
||||
@@ -1,26 +1,15 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* LUKS - Linux Unified Key Setup, keyslot unlock helpers
|
||||
*
|
||||
* Copyright (C) 2022-2023 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2022-2023 Ondrej Kozina
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* Copyright (C) 2022-2025 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2022-2025 Ondrej Kozina
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include "bitlk/bitlk.h"
|
||||
#include "fvault2/fvault2.h"
|
||||
#include "luks1/luks.h"
|
||||
#include "luks2/luks2.h"
|
||||
#include "keyslot_context.h"
|
||||
@@ -71,6 +60,44 @@ static int get_luks2_volume_key_by_passphrase(struct crypt_device *cd,
|
||||
return get_luks2_key_by_passphrase(cd, kc, keyslot, CRYPT_DEFAULT_SEGMENT, r_vk);
|
||||
}
|
||||
|
||||
static int get_bitlk_volume_key_by_passphrase(struct crypt_device *cd,
|
||||
struct crypt_keyslot_context *kc,
|
||||
const struct bitlk_metadata *params,
|
||||
struct volume_key **r_vk)
|
||||
{
|
||||
int r;
|
||||
|
||||
assert(cd);
|
||||
assert(kc && kc->type == CRYPT_KC_TYPE_PASSPHRASE);
|
||||
assert(params);
|
||||
assert(r_vk);
|
||||
|
||||
r = BITLK_get_volume_key(cd, kc->u.p.passphrase, kc->u.p.passphrase_size, params, r_vk);
|
||||
if (r < 0)
|
||||
kc->error = r;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int get_fvault2_volume_key_by_passphrase(struct crypt_device *cd,
|
||||
struct crypt_keyslot_context *kc,
|
||||
const struct fvault2_params *params,
|
||||
struct volume_key **r_vk)
|
||||
{
|
||||
int r;
|
||||
|
||||
assert(cd);
|
||||
assert(kc && kc->type == CRYPT_KC_TYPE_PASSPHRASE);
|
||||
assert(params);
|
||||
assert(r_vk);
|
||||
|
||||
r = FVAULT2_get_volume_key(cd, kc->u.p.passphrase, kc->u.p.passphrase_size, params, r_vk);
|
||||
if (r < 0)
|
||||
kc->error = r;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int get_passphrase_by_passphrase(struct crypt_device *cd,
|
||||
struct crypt_keyslot_context *kc,
|
||||
const char **r_passphrase,
|
||||
@@ -173,6 +200,56 @@ static int get_luks1_volume_key_by_keyfile(struct crypt_device *cd,
|
||||
return r;
|
||||
}
|
||||
|
||||
static int get_bitlk_volume_key_by_keyfile(struct crypt_device *cd,
|
||||
struct crypt_keyslot_context *kc,
|
||||
const struct bitlk_metadata *params,
|
||||
struct volume_key **r_vk)
|
||||
{
|
||||
int r;
|
||||
const char *passphrase;
|
||||
size_t passphrase_size;
|
||||
|
||||
assert(cd);
|
||||
assert(kc && kc->type == CRYPT_KC_TYPE_KEYFILE);
|
||||
assert(params);
|
||||
assert(r_vk);
|
||||
|
||||
r = get_passphrase_by_keyfile(cd, kc, &passphrase, &passphrase_size);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = BITLK_get_volume_key(cd, passphrase, passphrase_size, params, r_vk);
|
||||
if (r < 0)
|
||||
kc->error = r;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int get_fvault2_volume_key_by_keyfile(struct crypt_device *cd,
|
||||
struct crypt_keyslot_context *kc,
|
||||
const struct fvault2_params *params,
|
||||
struct volume_key **r_vk)
|
||||
{
|
||||
int r;
|
||||
const char *passphrase;
|
||||
size_t passphrase_size;
|
||||
|
||||
assert(cd);
|
||||
assert(kc && kc->type == CRYPT_KC_TYPE_KEYFILE);
|
||||
assert(params);
|
||||
assert(r_vk);
|
||||
|
||||
r = get_passphrase_by_keyfile(cd, kc, &passphrase, &passphrase_size);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = FVAULT2_get_volume_key(cd, passphrase, passphrase_size, params, r_vk);
|
||||
if (r < 0)
|
||||
kc->error = r;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int get_key_by_key(struct crypt_device *cd __attribute__((unused)),
|
||||
struct crypt_keyslot_context *kc,
|
||||
int keyslot __attribute__((unused)),
|
||||
@@ -211,6 +288,22 @@ static int get_generic_volume_key_by_key(struct crypt_device *cd,
|
||||
return get_key_by_key(cd, kc, -2 /* unused */, -2 /* unused */, r_vk);
|
||||
}
|
||||
|
||||
static int get_bitlk_volume_key_by_key(struct crypt_device *cd,
|
||||
struct crypt_keyslot_context *kc,
|
||||
const struct bitlk_metadata *params __attribute__((unused)),
|
||||
struct volume_key **r_vk)
|
||||
{
|
||||
return get_key_by_key(cd, kc, -2 /* unused */, -2 /* unused */, r_vk);
|
||||
}
|
||||
|
||||
static int get_fvault2_volume_key_by_key(struct crypt_device *cd,
|
||||
struct crypt_keyslot_context *kc,
|
||||
const struct fvault2_params *params __attribute__((unused)),
|
||||
struct volume_key **r_vk)
|
||||
{
|
||||
return get_key_by_key(cd, kc, -2 /* unused */, -2 /* unused */, r_vk);
|
||||
}
|
||||
|
||||
static int get_generic_signed_key_by_key(struct crypt_device *cd,
|
||||
struct crypt_keyslot_context *kc,
|
||||
struct volume_key **r_vk,
|
||||
@@ -367,7 +460,7 @@ static int get_luks2_key_by_keyring(struct crypt_device *cd,
|
||||
if (r < 0)
|
||||
kc->error = r;
|
||||
|
||||
return 0;
|
||||
return r;
|
||||
}
|
||||
|
||||
static int get_luks2_volume_key_by_keyring(struct crypt_device *cd,
|
||||
@@ -386,7 +479,7 @@ static int get_luks1_volume_key_by_keyring(struct crypt_device *cd,
|
||||
int r;
|
||||
|
||||
assert(cd);
|
||||
assert(kc && kc->type == CRYPT_KC_TYPE_PASSPHRASE);
|
||||
assert(kc && kc->type == CRYPT_KC_TYPE_KEYRING);
|
||||
assert(r_vk);
|
||||
|
||||
r = get_passphrase_by_keyring(cd, kc, CONST_CAST(const char **) &kc->i_passphrase,
|
||||
@@ -427,9 +520,9 @@ static int get_key_by_vk_in_keyring(struct crypt_device *cd,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
*r_vk = crypt_alloc_volume_key(key_size, key);
|
||||
crypt_safe_free(key);
|
||||
*r_vk = crypt_alloc_volume_key_by_safe_alloc((void **)&key);
|
||||
if (!*r_vk) {
|
||||
crypt_safe_free(key);
|
||||
kc->error = -ENOMEM;
|
||||
return kc->error;
|
||||
}
|
||||
@@ -445,16 +538,41 @@ static int get_volume_key_by_vk_in_keyring(struct crypt_device *cd,
|
||||
return get_key_by_vk_in_keyring(cd, kc, -2 /* unused */, -2 /* unused */, r_vk);
|
||||
}
|
||||
|
||||
static void unlock_method_init_internal(struct crypt_keyslot_context *kc)
|
||||
static void crypt_keyslot_context_init_common(struct crypt_keyslot_context *kc)
|
||||
{
|
||||
assert(kc);
|
||||
|
||||
kc->version = KC_VERSION_BASIC;
|
||||
kc->error = 0;
|
||||
kc->i_passphrase = NULL;
|
||||
kc->i_passphrase_size = 0;
|
||||
}
|
||||
|
||||
void crypt_keyslot_unlock_by_keyring_internal(struct crypt_keyslot_context *kc,
|
||||
static void keyring_context_free(struct crypt_keyslot_context *kc)
|
||||
{
|
||||
assert(kc && kc->type == CRYPT_KC_TYPE_KEYRING);
|
||||
|
||||
free(kc->u.kr.i_key_description);
|
||||
}
|
||||
|
||||
static int keyring_get_key_size(struct crypt_device *cd, struct crypt_keyslot_context *kc, size_t *r_key_size)
|
||||
{
|
||||
int r;
|
||||
|
||||
assert(kc && kc->type == CRYPT_KC_TYPE_VK_KEYRING);
|
||||
assert(r_key_size);
|
||||
|
||||
if (!kc->u.vk_kr.i_key_size) {
|
||||
r = crypt_keyring_get_keysize_by_name(cd, kc->u.vk_kr.key_description, &kc->u.vk_kr.i_key_size);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
*r_key_size = kc->u.vk_kr.i_key_size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void crypt_keyslot_context_init_by_keyring_internal(struct crypt_keyslot_context *kc,
|
||||
const char *key_description)
|
||||
{
|
||||
assert(kc);
|
||||
@@ -463,18 +581,32 @@ void crypt_keyslot_unlock_by_keyring_internal(struct crypt_keyslot_context *kc,
|
||||
kc->u.kr.key_description = key_description;
|
||||
|
||||
kc->get_luks2_key = get_luks2_key_by_keyring;
|
||||
kc->get_luks2_volume_key = get_luks2_volume_key_by_keyring;
|
||||
kc->get_luks1_volume_key = get_luks1_volume_key_by_keyring;
|
||||
kc->get_luks2_volume_key = get_luks2_volume_key_by_keyring;
|
||||
kc->get_passphrase = get_passphrase_by_keyring;
|
||||
kc->get_plain_volume_key = NULL;
|
||||
kc->get_bitlk_volume_key = NULL;
|
||||
kc->get_fvault2_volume_key = NULL;
|
||||
kc->get_verity_volume_key = NULL;
|
||||
kc->get_integrity_volume_key = NULL;
|
||||
unlock_method_init_internal(kc);
|
||||
kc->context_free = keyring_context_free;
|
||||
crypt_keyslot_context_init_common(kc);
|
||||
}
|
||||
|
||||
void crypt_keyslot_unlock_by_key_init_internal(struct crypt_keyslot_context *kc,
|
||||
static void key_context_free(struct crypt_keyslot_context *kc)
|
||||
{
|
||||
assert(kc && kc->type == CRYPT_KC_TYPE_KEY);
|
||||
|
||||
crypt_free_volume_key(kc->u.k.i_vk);
|
||||
}
|
||||
|
||||
static int key_get_key_size(struct crypt_device *cd __attribute__((unused)),
|
||||
struct crypt_keyslot_context *kc,
|
||||
size_t *r_key_size)
|
||||
{
|
||||
assert(kc && kc->type == CRYPT_KC_TYPE_KEY);
|
||||
assert(r_key_size);
|
||||
|
||||
*r_key_size = kc->u.k.volume_key_size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void crypt_keyslot_context_init_by_key_internal(struct crypt_keyslot_context *kc,
|
||||
const char *volume_key,
|
||||
size_t volume_key_size)
|
||||
{
|
||||
@@ -483,19 +615,29 @@ void crypt_keyslot_unlock_by_key_init_internal(struct crypt_keyslot_context *kc,
|
||||
kc->type = CRYPT_KC_TYPE_KEY;
|
||||
kc->u.k.volume_key = volume_key;
|
||||
kc->u.k.volume_key_size = volume_key_size;
|
||||
|
||||
kc->get_luks2_key = get_key_by_key;
|
||||
kc->get_luks2_volume_key = get_volume_key_by_key;
|
||||
kc->get_luks1_volume_key = get_volume_key_by_key;
|
||||
kc->get_passphrase = NULL; /* keyslot key context does not provide passphrase */
|
||||
kc->get_luks2_volume_key = get_volume_key_by_key;
|
||||
kc->get_plain_volume_key = get_generic_volume_key_by_key;
|
||||
kc->get_bitlk_volume_key = get_generic_volume_key_by_key;
|
||||
kc->get_fvault2_volume_key = get_generic_volume_key_by_key;
|
||||
kc->get_bitlk_volume_key = get_bitlk_volume_key_by_key;
|
||||
kc->get_fvault2_volume_key = get_fvault2_volume_key_by_key;
|
||||
kc->get_verity_volume_key = get_generic_signed_key_by_key;
|
||||
kc->get_integrity_volume_key = get_generic_volume_key_by_key;
|
||||
unlock_method_init_internal(kc);
|
||||
kc->get_key_size = key_get_key_size;
|
||||
kc->context_free = key_context_free;
|
||||
crypt_keyslot_context_init_common(kc);
|
||||
}
|
||||
|
||||
void crypt_keyslot_unlock_by_signed_key_init_internal(struct crypt_keyslot_context *kc,
|
||||
static void signed_key_context_free(struct crypt_keyslot_context *kc)
|
||||
{
|
||||
assert(kc && kc->type == CRYPT_KC_TYPE_SIGNED_KEY);
|
||||
|
||||
crypt_free_volume_key(kc->u.ks.i_vk);
|
||||
crypt_free_volume_key(kc->u.ks.i_vk_sig);
|
||||
}
|
||||
|
||||
void crypt_keyslot_context_init_by_signed_key_internal(struct crypt_keyslot_context *kc,
|
||||
const char *volume_key,
|
||||
size_t volume_key_size,
|
||||
const char *signature,
|
||||
@@ -508,19 +650,13 @@ void crypt_keyslot_unlock_by_signed_key_init_internal(struct crypt_keyslot_conte
|
||||
kc->u.ks.volume_key_size = volume_key_size;
|
||||
kc->u.ks.signature = signature;
|
||||
kc->u.ks.signature_size = signature_size;
|
||||
kc->get_luks2_key = NULL;
|
||||
kc->get_luks2_volume_key = NULL;
|
||||
kc->get_luks1_volume_key = NULL;
|
||||
kc->get_passphrase = NULL;
|
||||
kc->get_plain_volume_key = NULL;
|
||||
kc->get_bitlk_volume_key = NULL;
|
||||
kc->get_fvault2_volume_key = NULL;
|
||||
|
||||
kc->get_verity_volume_key = get_generic_signed_key_by_key;
|
||||
kc->get_integrity_volume_key = NULL;
|
||||
unlock_method_init_internal(kc);
|
||||
kc->context_free = signed_key_context_free;
|
||||
crypt_keyslot_context_init_common(kc);
|
||||
}
|
||||
|
||||
void crypt_keyslot_unlock_by_passphrase_init_internal(struct crypt_keyslot_context *kc,
|
||||
void crypt_keyslot_context_init_by_passphrase_internal(struct crypt_keyslot_context *kc,
|
||||
const char *passphrase,
|
||||
size_t passphrase_size)
|
||||
{
|
||||
@@ -529,19 +665,24 @@ void crypt_keyslot_unlock_by_passphrase_init_internal(struct crypt_keyslot_conte
|
||||
kc->type = CRYPT_KC_TYPE_PASSPHRASE;
|
||||
kc->u.p.passphrase = passphrase;
|
||||
kc->u.p.passphrase_size = passphrase_size;
|
||||
|
||||
kc->get_luks2_key = get_luks2_key_by_passphrase;
|
||||
kc->get_luks2_volume_key = get_luks2_volume_key_by_passphrase;
|
||||
kc->get_luks1_volume_key = get_luks1_volume_key_by_passphrase;
|
||||
kc->get_luks2_volume_key = get_luks2_volume_key_by_passphrase;
|
||||
kc->get_bitlk_volume_key = get_bitlk_volume_key_by_passphrase;
|
||||
kc->get_fvault2_volume_key = get_fvault2_volume_key_by_passphrase;
|
||||
kc->get_passphrase = get_passphrase_by_passphrase;
|
||||
kc->get_plain_volume_key = NULL;
|
||||
kc->get_bitlk_volume_key = NULL;
|
||||
kc->get_fvault2_volume_key = NULL;
|
||||
kc->get_verity_volume_key = NULL;
|
||||
kc->get_integrity_volume_key = NULL;
|
||||
unlock_method_init_internal(kc);
|
||||
crypt_keyslot_context_init_common(kc);
|
||||
}
|
||||
|
||||
void crypt_keyslot_unlock_by_keyfile_init_internal(struct crypt_keyslot_context *kc,
|
||||
static void keyfile_context_free(struct crypt_keyslot_context *kc)
|
||||
{
|
||||
assert(kc && kc->type == CRYPT_KC_TYPE_KEYFILE);
|
||||
|
||||
free(kc->u.kf.i_keyfile);
|
||||
}
|
||||
|
||||
void crypt_keyslot_context_init_by_keyfile_internal(struct crypt_keyslot_context *kc,
|
||||
const char *keyfile,
|
||||
size_t keyfile_size,
|
||||
uint64_t keyfile_offset)
|
||||
@@ -550,21 +691,28 @@ void crypt_keyslot_unlock_by_keyfile_init_internal(struct crypt_keyslot_context
|
||||
|
||||
kc->type = CRYPT_KC_TYPE_KEYFILE;
|
||||
kc->u.kf.keyfile = keyfile;
|
||||
kc->u.kf.keyfile_size = keyfile_size;
|
||||
kc->u.kf.keyfile_offset = keyfile_offset;
|
||||
kc->u.kf.keyfile_size = keyfile_size;
|
||||
|
||||
kc->get_luks2_key = get_luks2_key_by_keyfile;
|
||||
kc->get_luks2_volume_key = get_luks2_volume_key_by_keyfile;
|
||||
kc->get_luks1_volume_key = get_luks1_volume_key_by_keyfile;
|
||||
kc->get_luks2_volume_key = get_luks2_volume_key_by_keyfile;
|
||||
kc->get_bitlk_volume_key = get_bitlk_volume_key_by_keyfile;
|
||||
kc->get_fvault2_volume_key = get_fvault2_volume_key_by_keyfile;
|
||||
kc->get_passphrase = get_passphrase_by_keyfile;
|
||||
kc->get_plain_volume_key = NULL;
|
||||
kc->get_bitlk_volume_key = NULL;
|
||||
kc->get_fvault2_volume_key = NULL;
|
||||
kc->get_verity_volume_key = NULL;
|
||||
kc->get_integrity_volume_key = NULL;
|
||||
unlock_method_init_internal(kc);
|
||||
kc->context_free = keyfile_context_free;
|
||||
crypt_keyslot_context_init_common(kc);
|
||||
}
|
||||
|
||||
void crypt_keyslot_unlock_by_token_init_internal(struct crypt_keyslot_context *kc,
|
||||
static void token_context_free(struct crypt_keyslot_context *kc)
|
||||
{
|
||||
assert(kc && kc->type == CRYPT_KC_TYPE_TOKEN);
|
||||
|
||||
free(kc->u.t.i_type);
|
||||
crypt_safe_free(kc->u.t.i_pin);
|
||||
}
|
||||
|
||||
void crypt_keyslot_context_init_by_token_internal(struct crypt_keyslot_context *kc,
|
||||
int token,
|
||||
const char *type,
|
||||
const char *pin,
|
||||
@@ -579,47 +727,30 @@ void crypt_keyslot_unlock_by_token_init_internal(struct crypt_keyslot_context *k
|
||||
kc->u.t.pin = pin;
|
||||
kc->u.t.pin_size = pin_size;
|
||||
kc->u.t.usrptr = usrptr;
|
||||
|
||||
kc->get_luks2_key = get_luks2_key_by_token;
|
||||
kc->get_luks2_volume_key = get_luks2_volume_key_by_token;
|
||||
kc->get_luks1_volume_key = NULL; /* LUKS1 is not supported */
|
||||
kc->get_passphrase = get_passphrase_by_token;
|
||||
kc->get_plain_volume_key = NULL;
|
||||
kc->get_bitlk_volume_key = NULL;
|
||||
kc->get_fvault2_volume_key = NULL;
|
||||
kc->get_verity_volume_key = NULL;
|
||||
kc->get_integrity_volume_key = NULL;
|
||||
unlock_method_init_internal(kc);
|
||||
kc->context_free = token_context_free;
|
||||
crypt_keyslot_context_init_common(kc);
|
||||
}
|
||||
|
||||
void crypt_keyslot_unlock_by_vk_in_keyring_internal(struct crypt_keyslot_context *kc,
|
||||
const char *key_description)
|
||||
static void vk_in_keyring_context_free(struct crypt_keyslot_context *kc)
|
||||
{
|
||||
assert(kc);
|
||||
assert(kc && kc->type == CRYPT_KC_TYPE_VK_KEYRING);
|
||||
|
||||
kc->type = CRYPT_KC_TYPE_VK_KEYRING;
|
||||
kc->u.vk_kr.key_description = key_description;
|
||||
|
||||
kc->get_luks2_key = get_key_by_vk_in_keyring;
|
||||
kc->get_luks2_volume_key = get_volume_key_by_vk_in_keyring;
|
||||
kc->get_luks1_volume_key = NULL;
|
||||
kc->get_passphrase = NULL; /* keyslot key context does not provide passphrase */
|
||||
kc->get_plain_volume_key = NULL;
|
||||
kc->get_bitlk_volume_key = NULL;
|
||||
kc->get_fvault2_volume_key = NULL;
|
||||
kc->get_verity_volume_key = NULL;
|
||||
kc->get_integrity_volume_key = NULL;
|
||||
unlock_method_init_internal(kc);
|
||||
free(kc->u.vk_kr.i_key_description);
|
||||
}
|
||||
|
||||
|
||||
void crypt_keyslot_context_destroy_internal(struct crypt_keyslot_context *kc)
|
||||
{
|
||||
if (!kc)
|
||||
return;
|
||||
|
||||
if (kc->context_free)
|
||||
kc->context_free(kc);
|
||||
|
||||
crypt_safe_free(kc->i_passphrase);
|
||||
kc->i_passphrase = NULL;
|
||||
kc->i_passphrase_size = 0;
|
||||
}
|
||||
|
||||
void crypt_keyslot_context_free(struct crypt_keyslot_context *kc)
|
||||
@@ -628,155 +759,441 @@ void crypt_keyslot_context_free(struct crypt_keyslot_context *kc)
|
||||
free(kc);
|
||||
}
|
||||
|
||||
int crypt_keyslot_context_init_by_passphrase(struct crypt_device *cd __attribute__((unused)),
|
||||
const char *passphrase,
|
||||
static int _crypt_keyslot_context_init_by_passphrase(const char *passphrase,
|
||||
size_t passphrase_size,
|
||||
struct crypt_keyslot_context **kc)
|
||||
struct crypt_keyslot_context **kc,
|
||||
bool self_contained)
|
||||
{
|
||||
struct crypt_keyslot_context *tmp;
|
||||
char *i_passphrase = NULL;
|
||||
|
||||
if (!kc || !passphrase)
|
||||
return -EINVAL;
|
||||
|
||||
tmp = malloc(sizeof(*tmp));
|
||||
tmp = crypt_zalloc(sizeof(*tmp));
|
||||
if (!tmp)
|
||||
return -ENOMEM;
|
||||
|
||||
crypt_keyslot_unlock_by_passphrase_init_internal(tmp, passphrase, passphrase_size);
|
||||
if (self_contained) {
|
||||
if (passphrase_size) {
|
||||
i_passphrase = crypt_safe_alloc(passphrase_size);
|
||||
if (!i_passphrase) {
|
||||
free(tmp);
|
||||
return -ENOMEM;
|
||||
}
|
||||
crypt_safe_memcpy(i_passphrase, passphrase, passphrase_size);
|
||||
passphrase = i_passphrase;
|
||||
} else
|
||||
/*
|
||||
* some crypto backend libraries expect a pointer even though
|
||||
* passed passphrase size is set to zero.
|
||||
*/
|
||||
passphrase = "";
|
||||
}
|
||||
|
||||
crypt_keyslot_context_init_by_passphrase_internal(tmp, passphrase, passphrase_size);
|
||||
|
||||
if (self_contained) {
|
||||
tmp->i_passphrase = i_passphrase;
|
||||
tmp->i_passphrase_size = passphrase_size;
|
||||
tmp->version = KC_VERSION_SELF_CONTAINED;
|
||||
}
|
||||
|
||||
*kc = tmp;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypt_keyslot_context_init_by_keyfile(struct crypt_device *cd __attribute__((unused)),
|
||||
const char *keyfile,
|
||||
size_t keyfile_size,
|
||||
uint64_t keyfile_offset,
|
||||
CRYPT_SYMBOL_EXPORT_NEW(int, crypt_keyslot_context_init_by_passphrase, 2, 8,
|
||||
/* crypt_keyslot_context_init_by_passphrase parameters follows */
|
||||
struct crypt_device *cd __attribute__((unused)),
|
||||
const char *passphrase,
|
||||
size_t passphrase_size,
|
||||
struct crypt_keyslot_context **kc)
|
||||
{
|
||||
return _crypt_keyslot_context_init_by_passphrase(passphrase, passphrase_size, kc, true);
|
||||
}
|
||||
|
||||
CRYPT_SYMBOL_EXPORT_OLD(int, crypt_keyslot_context_init_by_passphrase, 2, 6,
|
||||
/* crypt_keyslot_context_init_by_passphrase parameters follows */
|
||||
struct crypt_device *cd __attribute__((unused)),
|
||||
const char *passphrase,
|
||||
size_t passphrase_size,
|
||||
struct crypt_keyslot_context **kc)
|
||||
{
|
||||
return _crypt_keyslot_context_init_by_passphrase(passphrase, passphrase_size, kc, false);
|
||||
}
|
||||
|
||||
static int _crypt_keyslot_context_init_by_keyfile(const char *keyfile,
|
||||
size_t keyfile_size,
|
||||
uint64_t keyfile_offset,
|
||||
struct crypt_keyslot_context **kc,
|
||||
bool self_contained)
|
||||
{
|
||||
char *i_keyfile;
|
||||
struct crypt_keyslot_context *tmp;
|
||||
|
||||
if (!kc || !keyfile)
|
||||
return -EINVAL;
|
||||
|
||||
tmp = malloc(sizeof(*tmp));
|
||||
tmp = crypt_zalloc(sizeof(*tmp));
|
||||
if (!tmp)
|
||||
return -ENOMEM;
|
||||
|
||||
crypt_keyslot_unlock_by_keyfile_init_internal(tmp, keyfile, keyfile_size, keyfile_offset);
|
||||
if (self_contained) {
|
||||
i_keyfile = strdup(keyfile);
|
||||
if (!i_keyfile) {
|
||||
free(tmp);
|
||||
return -ENOMEM;
|
||||
}
|
||||
keyfile = i_keyfile;
|
||||
}
|
||||
|
||||
crypt_keyslot_context_init_by_keyfile_internal(tmp, keyfile, keyfile_size, keyfile_offset);
|
||||
|
||||
if (self_contained) {
|
||||
tmp->u.kf.i_keyfile = i_keyfile;
|
||||
tmp->version = KC_VERSION_SELF_CONTAINED;
|
||||
}
|
||||
|
||||
*kc = tmp;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypt_keyslot_context_init_by_token(struct crypt_device *cd __attribute__((unused)),
|
||||
CRYPT_SYMBOL_EXPORT_NEW(int, crypt_keyslot_context_init_by_keyfile, 2, 8,
|
||||
/* crypt_keyslot_context_init_by_keyfile parameters follows */
|
||||
struct crypt_device *cd __attribute__((unused)),
|
||||
const char *keyfile,
|
||||
size_t keyfile_size,
|
||||
uint64_t keyfile_offset,
|
||||
struct crypt_keyslot_context **kc)
|
||||
{
|
||||
return _crypt_keyslot_context_init_by_keyfile(keyfile, keyfile_size, keyfile_offset, kc, true);
|
||||
}
|
||||
|
||||
CRYPT_SYMBOL_EXPORT_OLD(int, crypt_keyslot_context_init_by_keyfile, 2, 6,
|
||||
/* crypt_keyslot_context_init_by_keyfile parameters follows */
|
||||
struct crypt_device *cd __attribute__((unused)),
|
||||
const char *keyfile,
|
||||
size_t keyfile_size,
|
||||
uint64_t keyfile_offset,
|
||||
struct crypt_keyslot_context **kc)
|
||||
{
|
||||
return _crypt_keyslot_context_init_by_keyfile(keyfile, keyfile_size, keyfile_offset, kc, false);
|
||||
}
|
||||
|
||||
static int _crypt_keyslot_context_init_by_token(int token,
|
||||
const char *type,
|
||||
const char *pin, size_t pin_size,
|
||||
void *usrptr,
|
||||
struct crypt_keyslot_context **kc,
|
||||
bool self_contained)
|
||||
{
|
||||
char *i_type = NULL, *i_pin = NULL;
|
||||
struct crypt_keyslot_context *tmp;
|
||||
|
||||
if (!kc || (token < 0 && token != CRYPT_ANY_TOKEN) ||
|
||||
(pin && !pin_size))
|
||||
return -EINVAL;
|
||||
|
||||
tmp = crypt_zalloc(sizeof(*tmp));
|
||||
if (!tmp)
|
||||
return -ENOMEM;
|
||||
|
||||
if (self_contained && type) {
|
||||
if (!(i_type = strdup(type)))
|
||||
goto err;
|
||||
type = i_type;
|
||||
}
|
||||
|
||||
if (self_contained && pin) {
|
||||
if (!(i_pin = crypt_safe_alloc(pin_size)))
|
||||
goto err;
|
||||
crypt_safe_memcpy(i_pin, pin, pin_size);
|
||||
pin = i_pin;
|
||||
}
|
||||
|
||||
crypt_keyslot_context_init_by_token_internal(tmp, token, type, pin, pin_size, usrptr);
|
||||
|
||||
if (self_contained) {
|
||||
tmp->u.t.i_pin = i_pin;
|
||||
tmp->u.t.i_type = i_type;
|
||||
tmp->version = KC_VERSION_SELF_CONTAINED;
|
||||
}
|
||||
|
||||
*kc = tmp;
|
||||
|
||||
return 0;
|
||||
err:
|
||||
crypt_safe_free(i_pin);
|
||||
free(i_type);
|
||||
free(tmp);
|
||||
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
CRYPT_SYMBOL_EXPORT_NEW(int, crypt_keyslot_context_init_by_token, 2, 8,
|
||||
/* crypt_keyslot_context_init_by_token parameters follows */
|
||||
struct crypt_device *cd __attribute__((unused)),
|
||||
int token,
|
||||
const char *type,
|
||||
const char *pin, size_t pin_size,
|
||||
void *usrptr,
|
||||
struct crypt_keyslot_context **kc)
|
||||
{
|
||||
struct crypt_keyslot_context *tmp;
|
||||
|
||||
if (!kc || (token < 0 && token != CRYPT_ANY_TOKEN))
|
||||
return -EINVAL;
|
||||
|
||||
tmp = malloc(sizeof(*tmp));
|
||||
if (!tmp)
|
||||
return -ENOMEM;
|
||||
|
||||
crypt_keyslot_unlock_by_token_init_internal(tmp, token, type, pin, pin_size, usrptr);
|
||||
|
||||
*kc = tmp;
|
||||
|
||||
return 0;
|
||||
return _crypt_keyslot_context_init_by_token(token, type, pin, pin_size, usrptr, kc, true);
|
||||
}
|
||||
|
||||
int crypt_keyslot_context_init_by_volume_key(struct crypt_device *cd __attribute__((unused)),
|
||||
const char *volume_key,
|
||||
size_t volume_key_size,
|
||||
CRYPT_SYMBOL_EXPORT_OLD(int, crypt_keyslot_context_init_by_token, 2, 6,
|
||||
/* crypt_keyslot_context_init_by_token parameters follows */
|
||||
struct crypt_device *cd __attribute__((unused)),
|
||||
int token,
|
||||
const char *type,
|
||||
const char *pin, size_t pin_size,
|
||||
void *usrptr,
|
||||
struct crypt_keyslot_context **kc)
|
||||
{
|
||||
return _crypt_keyslot_context_init_by_token(token, type, pin, pin_size, usrptr, kc, false);
|
||||
}
|
||||
|
||||
static int _crypt_keyslot_context_init_by_volume_key(const char *volume_key,
|
||||
size_t volume_key_size,
|
||||
struct crypt_keyslot_context **kc,
|
||||
bool self_contained)
|
||||
{
|
||||
struct volume_key *i_vk = NULL;
|
||||
struct crypt_keyslot_context *tmp;
|
||||
|
||||
if (!kc)
|
||||
return -EINVAL;
|
||||
|
||||
tmp = malloc(sizeof(*tmp));
|
||||
tmp = crypt_zalloc(sizeof(*tmp));
|
||||
if (!tmp)
|
||||
return -ENOMEM;
|
||||
|
||||
crypt_keyslot_unlock_by_key_init_internal(tmp, volume_key, volume_key_size);
|
||||
if (self_contained && volume_key) {
|
||||
if (!(i_vk = crypt_alloc_volume_key(volume_key_size, volume_key))) {
|
||||
free(tmp);
|
||||
return -ENOMEM;
|
||||
}
|
||||
volume_key = crypt_volume_key_get_key(i_vk);
|
||||
}
|
||||
|
||||
crypt_keyslot_context_init_by_key_internal(tmp, volume_key, volume_key_size);
|
||||
|
||||
if (self_contained) {
|
||||
tmp->u.k.i_vk = i_vk;
|
||||
tmp->version = KC_VERSION_SELF_CONTAINED;
|
||||
}
|
||||
|
||||
*kc = tmp;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypt_keyslot_context_init_by_signed_key(struct crypt_device *cd __attribute__((unused)),
|
||||
CRYPT_SYMBOL_EXPORT_NEW(int, crypt_keyslot_context_init_by_volume_key, 2, 8,
|
||||
/* crypt_keyslot_context_init_by_volume_key parameters follows */
|
||||
struct crypt_device *cd __attribute__((unused)),
|
||||
const char *volume_key,
|
||||
size_t volume_key_size,
|
||||
struct crypt_keyslot_context **kc)
|
||||
{
|
||||
return _crypt_keyslot_context_init_by_volume_key(volume_key, volume_key_size, kc, true);
|
||||
}
|
||||
|
||||
CRYPT_SYMBOL_EXPORT_OLD(int, crypt_keyslot_context_init_by_volume_key, 2, 6,
|
||||
/* crypt_keyslot_context_init_by_volume_key parameters follows */
|
||||
struct crypt_device *cd __attribute__((unused)),
|
||||
const char *volume_key,
|
||||
size_t volume_key_size,
|
||||
struct crypt_keyslot_context **kc)
|
||||
{
|
||||
return _crypt_keyslot_context_init_by_volume_key(volume_key, volume_key_size, kc, false);
|
||||
}
|
||||
|
||||
static int _crypt_keyslot_context_init_by_signed_key(const char *volume_key,
|
||||
size_t volume_key_size,
|
||||
const char *signature,
|
||||
size_t signature_size,
|
||||
struct crypt_keyslot_context **kc,
|
||||
bool self_contained)
|
||||
{
|
||||
struct volume_key *i_vk = NULL, *i_vk_sig = NULL;
|
||||
struct crypt_keyslot_context *tmp;
|
||||
|
||||
if (!kc)
|
||||
return -EINVAL;
|
||||
|
||||
tmp = crypt_zalloc(sizeof(*tmp));
|
||||
if (!tmp)
|
||||
return -ENOMEM;
|
||||
|
||||
if (self_contained && volume_key) {
|
||||
if (!(i_vk = crypt_alloc_volume_key(volume_key_size, volume_key)))
|
||||
goto err;
|
||||
volume_key = crypt_volume_key_get_key(i_vk);
|
||||
}
|
||||
|
||||
if (self_contained && signature) {
|
||||
if (!(i_vk_sig = crypt_alloc_volume_key(signature_size, signature)))
|
||||
goto err;
|
||||
signature = crypt_volume_key_get_key(i_vk_sig);
|
||||
}
|
||||
|
||||
crypt_keyslot_context_init_by_signed_key_internal(tmp, volume_key, volume_key_size,
|
||||
signature, signature_size);
|
||||
|
||||
if (self_contained) {
|
||||
tmp->u.ks.i_vk = i_vk;
|
||||
tmp->u.ks.i_vk_sig = i_vk_sig;
|
||||
tmp->version = KC_VERSION_SELF_CONTAINED;
|
||||
}
|
||||
|
||||
*kc = tmp;
|
||||
|
||||
return 0;
|
||||
err:
|
||||
crypt_free_volume_key(i_vk);
|
||||
crypt_free_volume_key(i_vk_sig);
|
||||
free(tmp);
|
||||
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
CRYPT_SYMBOL_EXPORT_NEW(int, crypt_keyslot_context_init_by_signed_key, 2, 8,
|
||||
/* crypt_keyslot_context_init_by_signed_key parameters follows */
|
||||
struct crypt_device *cd __attribute__((unused)),
|
||||
const char *volume_key,
|
||||
size_t volume_key_size,
|
||||
const char *signature,
|
||||
size_t signature_size,
|
||||
struct crypt_keyslot_context **kc)
|
||||
{
|
||||
return _crypt_keyslot_context_init_by_signed_key(volume_key, volume_key_size, signature, signature_size, kc, true);
|
||||
}
|
||||
|
||||
CRYPT_SYMBOL_EXPORT_OLD(int, crypt_keyslot_context_init_by_signed_key, 2, 7,
|
||||
/* crypt_keyslot_context_init_by_signed_key parameters follows */
|
||||
struct crypt_device *cd __attribute__((unused)),
|
||||
const char *volume_key,
|
||||
size_t volume_key_size,
|
||||
const char *signature,
|
||||
size_t signature_size,
|
||||
struct crypt_keyslot_context **kc)
|
||||
{
|
||||
return _crypt_keyslot_context_init_by_signed_key(volume_key, volume_key_size, signature, signature_size, kc, false);
|
||||
}
|
||||
|
||||
static int _crypt_keyslot_context_init_by_keyring(const char *key_description,
|
||||
struct crypt_keyslot_context **kc,
|
||||
bool self_contained)
|
||||
{
|
||||
char *i_key_description;
|
||||
struct crypt_keyslot_context *tmp;
|
||||
|
||||
if (!kc)
|
||||
if (!kc || !key_description)
|
||||
return -EINVAL;
|
||||
|
||||
tmp = malloc(sizeof(*tmp));
|
||||
tmp = crypt_zalloc(sizeof(*tmp));
|
||||
if (!tmp)
|
||||
return -ENOMEM;
|
||||
|
||||
crypt_keyslot_unlock_by_signed_key_init_internal(tmp, volume_key, volume_key_size,
|
||||
signature, signature_size);
|
||||
if (self_contained) {
|
||||
if (!(i_key_description = strdup(key_description))) {
|
||||
free(tmp);
|
||||
return -ENOMEM;
|
||||
}
|
||||
key_description = i_key_description;
|
||||
}
|
||||
|
||||
crypt_keyslot_context_init_by_keyring_internal(tmp, key_description);
|
||||
|
||||
if (self_contained) {
|
||||
tmp->u.kr.i_key_description = i_key_description;
|
||||
tmp->version = KC_VERSION_SELF_CONTAINED;
|
||||
}
|
||||
|
||||
*kc = tmp;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypt_keyslot_context_init_by_keyring(struct crypt_device *cd __attribute__((unused)),
|
||||
CRYPT_SYMBOL_EXPORT_NEW(int, crypt_keyslot_context_init_by_keyring, 2, 8,
|
||||
/* crypt_keyslot_context_init_by_keyring parameters follows */
|
||||
struct crypt_device *cd __attribute__((unused)),
|
||||
const char *key_description,
|
||||
struct crypt_keyslot_context **kc)
|
||||
{
|
||||
return _crypt_keyslot_context_init_by_keyring(key_description, kc, true);
|
||||
}
|
||||
|
||||
CRYPT_SYMBOL_EXPORT_OLD(int, crypt_keyslot_context_init_by_keyring, 2, 7,
|
||||
/* crypt_keyslot_context_init_by_keyring parameters follows */
|
||||
struct crypt_device *cd __attribute__((unused)),
|
||||
const char *key_description,
|
||||
struct crypt_keyslot_context **kc)
|
||||
{
|
||||
return _crypt_keyslot_context_init_by_keyring(key_description, kc, false);
|
||||
}
|
||||
|
||||
static int _crypt_keyslot_context_init_by_vk_in_keyring(const char *key_description,
|
||||
struct crypt_keyslot_context **kc,
|
||||
bool self_contained)
|
||||
{
|
||||
char *i_key_description;
|
||||
struct crypt_keyslot_context *tmp;
|
||||
|
||||
if (!kc)
|
||||
if (!kc || !key_description)
|
||||
return -EINVAL;
|
||||
|
||||
tmp = malloc(sizeof(*tmp));
|
||||
tmp = crypt_zalloc(sizeof(*tmp));
|
||||
if (!tmp)
|
||||
return -ENOMEM;
|
||||
|
||||
crypt_keyslot_unlock_by_keyring_internal(tmp, key_description);
|
||||
if (self_contained) {
|
||||
if (!(i_key_description = strdup(key_description))) {
|
||||
free(tmp);
|
||||
return -ENOMEM;
|
||||
}
|
||||
key_description = i_key_description;
|
||||
}
|
||||
|
||||
tmp->type = CRYPT_KC_TYPE_VK_KEYRING;
|
||||
tmp->u.vk_kr.key_description = key_description;
|
||||
|
||||
tmp->get_luks2_key = get_key_by_vk_in_keyring;
|
||||
tmp->get_luks2_volume_key = get_volume_key_by_vk_in_keyring;
|
||||
tmp->get_key_size = keyring_get_key_size;
|
||||
tmp->context_free = vk_in_keyring_context_free;
|
||||
crypt_keyslot_context_init_common(tmp);
|
||||
|
||||
if (self_contained) {
|
||||
tmp->u.vk_kr.i_key_description = i_key_description;
|
||||
tmp->version = KC_VERSION_SELF_CONTAINED;
|
||||
}
|
||||
|
||||
*kc = tmp;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypt_keyslot_context_init_by_vk_in_keyring(struct crypt_device *cd __attribute__((unused)),
|
||||
CRYPT_SYMBOL_EXPORT_NEW(int, crypt_keyslot_context_init_by_vk_in_keyring, 2, 8,
|
||||
/* crypt_keyslot_context_init_by_vk_in_keyring parameters follows */
|
||||
struct crypt_device *cd __attribute__((unused)),
|
||||
const char *key_description,
|
||||
struct crypt_keyslot_context **kc)
|
||||
{
|
||||
struct crypt_keyslot_context *tmp;
|
||||
return _crypt_keyslot_context_init_by_vk_in_keyring(key_description, kc, true);
|
||||
}
|
||||
|
||||
if (!kc)
|
||||
return -EINVAL;
|
||||
|
||||
tmp = malloc(sizeof(*tmp));
|
||||
if (!tmp)
|
||||
return -ENOMEM;
|
||||
|
||||
crypt_keyslot_unlock_by_vk_in_keyring_internal(tmp, key_description);
|
||||
|
||||
*kc = tmp;
|
||||
|
||||
return 0;
|
||||
CRYPT_SYMBOL_EXPORT_OLD(int, crypt_keyslot_context_init_by_vk_in_keyring, 2, 7,
|
||||
/* crypt_keyslot_context_init_by_vk_in_keyring parameters follows */
|
||||
struct crypt_device *cd __attribute__((unused)),
|
||||
const char *key_description,
|
||||
struct crypt_keyslot_context **kc)
|
||||
{
|
||||
return _crypt_keyslot_context_init_by_vk_in_keyring(key_description, kc, false);
|
||||
}
|
||||
|
||||
int crypt_keyslot_context_get_error(struct crypt_keyslot_context *kc)
|
||||
@@ -788,10 +1205,21 @@ int crypt_keyslot_context_set_pin(struct crypt_device *cd __attribute__((unused)
|
||||
const char *pin, size_t pin_size,
|
||||
struct crypt_keyslot_context *kc)
|
||||
{
|
||||
char *i_pin = NULL;
|
||||
|
||||
if (!kc || kc->type != CRYPT_KC_TYPE_TOKEN)
|
||||
return -EINVAL;
|
||||
|
||||
kc->u.t.pin = pin;
|
||||
if (kc->version >= KC_VERSION_SELF_CONTAINED && pin) {
|
||||
if (!(i_pin = crypt_safe_alloc(pin_size)))
|
||||
return -ENOMEM;
|
||||
crypt_safe_memcpy(i_pin, pin, pin_size);
|
||||
}
|
||||
|
||||
crypt_safe_free(kc->u.t.i_pin);
|
||||
kc->u.t.i_pin = i_pin;
|
||||
|
||||
kc->u.t.pin = i_pin ?: pin;
|
||||
kc->u.t.pin_size = pin_size;
|
||||
kc->error = 0;
|
||||
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* LUKS - Linux Unified Key Setup, keyslot unlock helpers
|
||||
*
|
||||
* Copyright (C) 2022-2023 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2022-2023 Ondrej Kozina
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* Copyright (C) 2022-2025 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2022-2025 Ondrej Kozina
|
||||
*/
|
||||
|
||||
#ifndef KEYSLOT_CONTEXT_H
|
||||
@@ -27,6 +14,9 @@
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
struct bitlk_metadata;
|
||||
struct fvault2_params;
|
||||
|
||||
typedef int (*keyslot_context_get_key) (
|
||||
struct crypt_device *cd,
|
||||
struct crypt_keyslot_context *kc,
|
||||
@@ -45,6 +35,19 @@ typedef int (*keyslot_context_get_generic_volume_key) (
|
||||
struct crypt_keyslot_context *kc,
|
||||
struct volume_key **r_vk);
|
||||
|
||||
typedef int (*keyslot_context_get_bitlk_volume_key) (
|
||||
struct crypt_device *cd,
|
||||
struct crypt_keyslot_context *kc,
|
||||
const struct bitlk_metadata *params,
|
||||
struct volume_key **r_vk);
|
||||
|
||||
typedef int (*keyslot_context_get_fvault2_volume_key) (
|
||||
struct crypt_device *cd,
|
||||
struct crypt_keyslot_context *kc,
|
||||
const struct fvault2_params *params,
|
||||
struct volume_key **r_vk);
|
||||
|
||||
|
||||
typedef int (*keyslot_context_get_generic_signed_key) (
|
||||
struct crypt_device *cd,
|
||||
struct crypt_keyslot_context *kc,
|
||||
@@ -57,10 +60,28 @@ typedef int (*keyslot_context_get_passphrase) (
|
||||
const char **r_passphrase,
|
||||
size_t *r_passphrase_size);
|
||||
|
||||
typedef void (*keyslot_context_free) (
|
||||
struct crypt_keyslot_context *kc);
|
||||
|
||||
typedef int (*keyslot_context_get_key_size) (
|
||||
struct crypt_device *cd,
|
||||
struct crypt_keyslot_context *kc,
|
||||
size_t *r_key_size);
|
||||
|
||||
#define KC_VERSION_BASIC UINT8_C(1)
|
||||
#define KC_VERSION_SELF_CONTAINED UINT8_C(2)
|
||||
|
||||
/* crypt_keyslot_context */
|
||||
struct crypt_keyslot_context {
|
||||
int type;
|
||||
|
||||
/* versions:
|
||||
* v1: All passed pointers (e.g.: type, passphrase, keyfile,...) must
|
||||
* be valid after ctx initialization.
|
||||
* v2: Fully self-contained
|
||||
*/
|
||||
uint8_t version;
|
||||
|
||||
union {
|
||||
struct {
|
||||
const char *passphrase;
|
||||
@@ -68,31 +89,40 @@ struct crypt_keyslot_context {
|
||||
} p;
|
||||
struct {
|
||||
const char *keyfile;
|
||||
char *i_keyfile;
|
||||
uint64_t keyfile_offset;
|
||||
size_t keyfile_size;
|
||||
} kf;
|
||||
struct {
|
||||
int id;
|
||||
const char *type;
|
||||
char *i_type;
|
||||
const char *pin;
|
||||
char *i_pin;
|
||||
size_t pin_size;
|
||||
void *usrptr;
|
||||
} t;
|
||||
struct {
|
||||
const char *volume_key;
|
||||
size_t volume_key_size;
|
||||
struct volume_key *i_vk;
|
||||
} k;
|
||||
struct {
|
||||
const char *volume_key;
|
||||
size_t volume_key_size;
|
||||
struct volume_key *i_vk;
|
||||
const char *signature;
|
||||
size_t signature_size;
|
||||
struct volume_key *i_vk_sig;
|
||||
} ks;
|
||||
struct {
|
||||
const char *key_description;
|
||||
char *i_key_description;
|
||||
} kr;
|
||||
struct {
|
||||
const char *key_description;
|
||||
char *i_key_description;
|
||||
size_t i_key_size;
|
||||
} vk_kr;
|
||||
} u;
|
||||
|
||||
@@ -105,45 +135,44 @@ struct crypt_keyslot_context {
|
||||
keyslot_context_get_volume_key get_luks1_volume_key;
|
||||
keyslot_context_get_volume_key get_luks2_volume_key;
|
||||
keyslot_context_get_generic_volume_key get_plain_volume_key;
|
||||
keyslot_context_get_generic_volume_key get_bitlk_volume_key;
|
||||
keyslot_context_get_generic_volume_key get_fvault2_volume_key;
|
||||
keyslot_context_get_bitlk_volume_key get_bitlk_volume_key;
|
||||
keyslot_context_get_fvault2_volume_key get_fvault2_volume_key;
|
||||
keyslot_context_get_generic_signed_key get_verity_volume_key;
|
||||
keyslot_context_get_generic_volume_key get_integrity_volume_key;
|
||||
keyslot_context_get_passphrase get_passphrase;
|
||||
keyslot_context_get_key_size get_key_size;
|
||||
keyslot_context_free context_free;
|
||||
};
|
||||
|
||||
void crypt_keyslot_context_destroy_internal(struct crypt_keyslot_context *method);
|
||||
|
||||
void crypt_keyslot_unlock_by_key_init_internal(struct crypt_keyslot_context *kc,
|
||||
void crypt_keyslot_context_init_by_key_internal(struct crypt_keyslot_context *kc,
|
||||
const char *volume_key,
|
||||
size_t volume_key_size);
|
||||
|
||||
void crypt_keyslot_unlock_by_signed_key_init_internal(struct crypt_keyslot_context *kc,
|
||||
void crypt_keyslot_context_init_by_signed_key_internal(struct crypt_keyslot_context *kc,
|
||||
const char *volume_key,
|
||||
size_t volume_key_size,
|
||||
const char *signature,
|
||||
size_t signature_size);
|
||||
|
||||
void crypt_keyslot_unlock_by_passphrase_init_internal(struct crypt_keyslot_context *kc,
|
||||
void crypt_keyslot_context_init_by_passphrase_internal(struct crypt_keyslot_context *kc,
|
||||
const char *passphrase,
|
||||
size_t passphrase_size);
|
||||
|
||||
void crypt_keyslot_unlock_by_keyfile_init_internal(struct crypt_keyslot_context *kc,
|
||||
void crypt_keyslot_context_init_by_keyfile_internal(struct crypt_keyslot_context *kc,
|
||||
const char *keyfile,
|
||||
size_t keyfile_size,
|
||||
uint64_t keyfile_offset);
|
||||
|
||||
void crypt_keyslot_unlock_by_token_init_internal(struct crypt_keyslot_context *kc,
|
||||
void crypt_keyslot_context_init_by_token_internal(struct crypt_keyslot_context *kc,
|
||||
int token,
|
||||
const char *type,
|
||||
const char *pin,
|
||||
size_t pin_size,
|
||||
void *usrptr);
|
||||
|
||||
void crypt_keyslot_unlock_by_keyring_internal(struct crypt_keyslot_context *kc,
|
||||
const char *key_description);
|
||||
|
||||
void crypt_keyslot_unlock_by_vk_in_keyring_internal(struct crypt_keyslot_context *kc,
|
||||
void crypt_keyslot_context_init_by_keyring_internal(struct crypt_keyslot_context *kc,
|
||||
const char *key_description);
|
||||
|
||||
const char *keyslot_context_type_string(const struct crypt_keyslot_context *kc);
|
||||
|
||||
@@ -1,24 +1,11 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
* libcryptsetup - cryptsetup library
|
||||
*
|
||||
* Copyright (C) 2004 Jana Saout <jana@saout.de>
|
||||
* Copyright (C) 2004-2007 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2023 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2023 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* Copyright (C) 2009-2025 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2025 Milan Broz
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -607,7 +594,7 @@ struct crypt_params_integrity {
|
||||
uint32_t sector_size; /**< sector size in bytes */
|
||||
uint32_t buffer_sectors; /**< number of sectors in one buffer */
|
||||
const char *integrity; /**< integrity algorithm, NULL for LUKS2 */
|
||||
uint32_t integrity_key_size; /**< integrity key size in bytes, info only, 0 for LUKS2 */
|
||||
uint32_t integrity_key_size; /**< integrity key size in bytes, info only */
|
||||
|
||||
const char *journal_integrity; /**< journal integrity algorithm */
|
||||
const char *journal_integrity_key; /**< journal integrity key, only for crypt_load */
|
||||
@@ -697,8 +684,8 @@ int crypt_format(struct crypt_device *cd,
|
||||
* @param cipher for SW encryption (e.g. "aes") or NULL for HW encryption only
|
||||
* @param cipher_mode including IV specification (e.g. "xts-plain") or NULL for HW encryption only
|
||||
* @param uuid requested UUID or @e NULL if it should be generated
|
||||
* @param volume_key pre-generated volume key or @e NULL if it should be generated (only for LUKS2 SW encryption)
|
||||
* @param volume_key_size size of volume key in bytes (only for SW encryption).
|
||||
* @param volume_keys pre-generated volume keys or @e NULL if it should be generated (only for LUKS2 SW encryption)
|
||||
* @param volume_keys_size size of volume keys in bytes (only for SW encryption).
|
||||
* @param params LUKS2 crypt type specific parameters (see @link crypt-type @endlink)
|
||||
* @param opal_params OPAL specific parameters
|
||||
*
|
||||
@@ -716,6 +703,35 @@ int crypt_format_luks2_opal(struct crypt_device *cd,
|
||||
struct crypt_params_luks2 *params,
|
||||
struct crypt_params_hw_opal *opal_params);
|
||||
|
||||
/**
|
||||
* Create (format) new integrity-protected device using integrity inline mode (HW sector tags).
|
||||
* This can be used for @e INTEGRITY and @e LUKS2 with integrity protection
|
||||
*
|
||||
* @pre @e cd contains initialized and not formatted device context (device type must @b not be set)
|
||||
*
|
||||
* @param cd crypt device handle
|
||||
* @param type type of device (optional params struct must be of this type)
|
||||
* @param cipher (e.g. "aes") or @e NULL for @e INTEGRITY
|
||||
* @param cipher_mode including IV specification (e.g. "xts-plain") or @e NULL for @e INTEGRITY
|
||||
* @param uuid requested UUID or @e NULL if it should be generated
|
||||
* @param volume_key pre-generated integrity/volume key (if needed) or @e NULL
|
||||
* @param volume_key_size size of volume/integrity key in bytes.
|
||||
* @param params crypt type specific parameters (see @link crypt-type @endlink)
|
||||
*
|
||||
* @returns @e 0 on success or negative errno value otherwise.
|
||||
*
|
||||
* @note Journal parameters must be set to zero in integrity part of @e params.
|
||||
* Only tag_size, sector_size, buffer_sectors, integrity options should be set.
|
||||
*/
|
||||
int crypt_format_inline(struct crypt_device *cd,
|
||||
const char *type,
|
||||
const char *cipher,
|
||||
const char *cipher_mode,
|
||||
const char *uuid,
|
||||
const char *volume_key,
|
||||
size_t volume_key_size,
|
||||
void *params);
|
||||
|
||||
/**
|
||||
* Set format compatibility flags.
|
||||
*
|
||||
@@ -964,7 +980,7 @@ int crypt_resume_by_keyfile(struct crypt_device *cd,
|
||||
* @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
|
||||
* @param volume_key_size size of volume_key in bytes
|
||||
*
|
||||
* @return @e 0 on success or negative errno value otherwise.
|
||||
*/
|
||||
@@ -1136,7 +1152,7 @@ int crypt_keyslot_add_by_keyfile(struct crypt_device *cd,
|
||||
* @param cd crypt device handle
|
||||
* @param keyslot requested keyslot or CRYPT_ANY_SLOT
|
||||
* @param volume_key provided volume key or @e NULL if used after crypt_format
|
||||
* @param volume_key_size size of volume_key
|
||||
* @param volume_key_size size of volume_key in bytes
|
||||
* @param passphrase passphrase for new keyslot
|
||||
* @param passphrase_size size of passphrase
|
||||
*
|
||||
@@ -1166,7 +1182,7 @@ int crypt_keyslot_add_by_volume_key(struct crypt_device *cd,
|
||||
* @param cd crypt device handle
|
||||
* @param keyslot requested keyslot or CRYPT_ANY_SLOT
|
||||
* @param volume_key provided volume key or @e NULL (see note below)
|
||||
* @param volume_key_size size of volume_key
|
||||
* @param volume_key_size size of volume_key in bytes
|
||||
* @param passphrase passphrase for new keyslot
|
||||
* @param passphrase_size size of passphrase
|
||||
* @param flags key flags to set
|
||||
@@ -1217,6 +1233,10 @@ void crypt_keyslot_context_free(struct crypt_keyslot_context *kc);
|
||||
* @param kc returns crypt keyslot context handle type CRYPT_KC_TYPE_PASSPHRASE
|
||||
*
|
||||
* @return zero on success or negative errno otherwise.
|
||||
*
|
||||
* @note The original buffer containing passphrase passed in parameters does
|
||||
* not have to be valid after context initialization. The context
|
||||
* contains copy of the original before freed with @link crypt_keyslot_context_free @endlink.
|
||||
*/
|
||||
int crypt_keyslot_context_init_by_passphrase(struct crypt_device *cd,
|
||||
const char *passphrase,
|
||||
@@ -1269,7 +1289,7 @@ int crypt_keyslot_context_init_by_token(struct crypt_device *cd,
|
||||
*
|
||||
* @param volume_key provided volume key or @e NULL if used after crypt_format
|
||||
* or with CRYPT_VOLUME_KEY_NO_SEGMENT flag
|
||||
* @param volume_key_size size of volume_key
|
||||
* @param volume_key_size size of volume_key in bytes
|
||||
* @param kc returns crypt keyslot context handle type CRYPT_KC_TYPE_KEY
|
||||
*
|
||||
* @return zero on success or negative errno otherwise.
|
||||
@@ -1285,9 +1305,9 @@ int crypt_keyslot_context_init_by_volume_key(struct crypt_device *cd,
|
||||
* @param cd crypt device handle initialized to device context
|
||||
*
|
||||
* @param volume_key provided volume key
|
||||
* @param volume_key_size size of volume_key
|
||||
* @param volume_key_size size of volume_key in bytes
|
||||
* @param signature buffer with signature for the key
|
||||
* @param signature_size bsize of signature buffer
|
||||
* @param signature_size size of signature buffer
|
||||
* @param kc returns crypt keyslot context handle type CRYPT_KC_TYPE_SIGNED_KEY
|
||||
*
|
||||
* @return zero on success or negative errno otherwise.
|
||||
@@ -1363,7 +1383,7 @@ int crypt_keyslot_context_set_pin(struct crypt_device *cd,
|
||||
struct crypt_keyslot_context *kc);
|
||||
|
||||
/**
|
||||
* @defgroup crypt-keyslot-context-types Crypt keyslot context
|
||||
* @defgroup crypt-keyslot-context-types Crypt keyslot context types
|
||||
* @addtogroup crypt-keyslot-context-types
|
||||
* @{
|
||||
*/
|
||||
@@ -1517,6 +1537,12 @@ int crypt_keyslot_destroy(struct crypt_device *cd, int keyslot);
|
||||
#define CRYPT_ACTIVATE_RECALCULATE_RESET (UINT32_C(1) << 26)
|
||||
/** dm-verity: try to use tasklets */
|
||||
#define CRYPT_ACTIVATE_TASKLETS (UINT32_C(1) << 27)
|
||||
/** dm-crypt: use high-priority workqueues */
|
||||
#define CRYPT_ACTIVATE_HIGH_PRIORITY (UINT32_C(1) << 28)
|
||||
/** dm-verity: also restart/panic on error, use with RESTART_ON_CORRUPTION or PANIC_ON_CORRUPTION */
|
||||
#define CRYPT_ACTIVATE_ERROR_AS_CORRUPTION (UINT32_C(1) << 29)
|
||||
/** dm-integrity: inline mode for compatible hardware profile */
|
||||
#define CRYPT_ACTIVATE_INLINE_MODE (UINT32_C(1) << 30)
|
||||
|
||||
/**
|
||||
* Active device runtime attributes
|
||||
@@ -1570,6 +1596,8 @@ uint64_t crypt_get_active_integrity_failures(struct crypt_device *cd,
|
||||
#define CRYPT_REQUIREMENT_ONLINE_REENCRYPT (UINT32_C(1) << 1)
|
||||
/** Device configured with OPAL support */
|
||||
#define CRYPT_REQUIREMENT_OPAL (UINT32_C(1) << 2)
|
||||
/** Device configured with inline HW tags */
|
||||
#define CRYPT_REQUIREMENT_INLINE_HW_TAGS (UINT32_C(1) << 3)
|
||||
/** unknown requirement in header (output only) */
|
||||
#define CRYPT_REQUIREMENT_UNKNOWN (UINT32_C(1) << 31)
|
||||
|
||||
@@ -1592,9 +1620,11 @@ typedef enum {
|
||||
*
|
||||
* @note Valid only for LUKS2.
|
||||
*
|
||||
* @note Not all activation flags can be stored. Only ALLOW_DISCARD,
|
||||
* SAME_CPU_CRYPT, SUBMIT_FROM_CRYPT_CPU and NO_JOURNAL can be
|
||||
* stored persistently.
|
||||
* @note Not all activation flags can be stored. Only CRYPT_ACTIVATE_ALLOW_DISCARDS,
|
||||
* CRYPT_ACTIVATE_SAME_CPU_CRYPT, CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS,
|
||||
* CRYPT_ACTIVATE_NO_JOURNAL, CRYPT_ACTIVATE_NO_READ_WORKQUEUE,
|
||||
* CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE and CRYPT_ACTIVATE_HIGH_PRIORITY
|
||||
* can be stored persistently.
|
||||
*
|
||||
* @note Only requirements flags recognised by current library may be set.
|
||||
* CRYPT_REQUIREMENT_UNKNOWN is illegal (output only) in set operation.
|
||||
@@ -1624,13 +1654,25 @@ int crypt_persistent_flags_get(struct crypt_device *cd,
|
||||
*/
|
||||
|
||||
/**
|
||||
* Activate device or check using keyslot context.
|
||||
* Activate device or check using keyslot context. In some cases (device under
|
||||
* reencryption), more than one keyslot context is required (e.g. one for the old
|
||||
* volume key and one for the new volume key). The order of the keyslot
|
||||
* contexts does not matter. When less keyslot contexts are supplied than
|
||||
* required to unlock the device an -ESRCH error code is returned and you
|
||||
* should call the function again with an additional keyslot context specified.
|
||||
*
|
||||
* NOTE: the API at the moment fully works for single keyslot context only,
|
||||
* the additional keyslot context currently works only with
|
||||
* @e CRYPT_KC_TYPE_VK_KEYRING or @e CRYPT_KC_TYPE_KEY contexts.
|
||||
*
|
||||
* @param cd crypt device handle
|
||||
* @param name name of device to create, if @e NULL only check passphrase
|
||||
* @param keyslot requested keyslot to check or @e CRYPT_ANY_SLOT, keyslot is
|
||||
* ignored for unlock methods not based on passphrase
|
||||
* @param kc keyslot context providing volume key or passphrase.
|
||||
* @param additional_keyslot requested additional keyslot to check or @e CRYPT_ANY_SLOT
|
||||
* @param additional_kc keyslot context providing additional volume key or
|
||||
* passphrase (e.g. old volume key for device under reencryption).
|
||||
* @param flags activation flags
|
||||
*
|
||||
* @return unlocked key slot number for passphrase-based unlock, zero for other
|
||||
@@ -1640,6 +1682,8 @@ int crypt_activate_by_keyslot_context(struct crypt_device *cd,
|
||||
const char *name,
|
||||
int keyslot,
|
||||
struct crypt_keyslot_context *kc,
|
||||
int additional_keyslot,
|
||||
struct crypt_keyslot_context *additional_kc,
|
||||
uint32_t flags);
|
||||
|
||||
/**
|
||||
@@ -1709,7 +1753,7 @@ int crypt_activate_by_keyfile(struct crypt_device *cd,
|
||||
* @param cd crypt device handle
|
||||
* @param name name of device to create, if @e NULL only check volume key
|
||||
* @param volume_key provided volume key (or @e NULL to use internal)
|
||||
* @param volume_key_size size of volume_key
|
||||
* @param volume_key_size size of volume_key in bytes
|
||||
* @param flags activation flags
|
||||
*
|
||||
* @return @e 0 on success or negative errno value otherwise.
|
||||
@@ -1722,9 +1766,9 @@ int crypt_activate_by_keyfile(struct crypt_device *cd,
|
||||
* CRYPT_ACTIVATE_READONLY flag always.
|
||||
* @note For TCRYPT the volume key should be always NULL
|
||||
* the key from decrypted header is used instead.
|
||||
* @note For BITLK @name cannot be @e NULL checking volume key is not
|
||||
* supported for BITLK, the device will be activated even if the
|
||||
* provided key is not correct.
|
||||
* @note For BITLK the name cannot be @e NULL checking volume key is not
|
||||
* supported for BITLK, the device will be activated even if the
|
||||
* provided key is not correct.
|
||||
*/
|
||||
int crypt_activate_by_volume_key(struct crypt_device *cd,
|
||||
const char *name,
|
||||
@@ -1738,9 +1782,9 @@ int crypt_activate_by_volume_key(struct crypt_device *cd,
|
||||
* @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 volume_key_size size of volume_key in bytes
|
||||
* @param signature buffer with signature for the key
|
||||
* @param signature_size bsize of signature buffer
|
||||
* @param signature_size size of signature buffer
|
||||
* @param flags activation flags
|
||||
*
|
||||
* @return @e 0 on success or negative errno value otherwise.
|
||||
@@ -1821,7 +1865,7 @@ int crypt_deactivate(struct crypt_device *cd, const char *name);
|
||||
* @param keyslot use this keyslot or @e CRYPT_ANY_SLOT
|
||||
* @param volume_key buffer for volume key
|
||||
* @param volume_key_size on input, size of buffer @e volume_key,
|
||||
* on output size of @e volume_key
|
||||
* on output size of @e volume_key in bytes
|
||||
* @param passphrase passphrase used to unlock volume key
|
||||
* @param passphrase_size size of @e passphrase
|
||||
*
|
||||
@@ -1848,7 +1892,7 @@ int crypt_volume_key_get(struct crypt_device *cd,
|
||||
* @param keyslot use this keyslot or @e CRYPT_ANY_SLOT
|
||||
* @param volume_key buffer for volume key
|
||||
* @param volume_key_size on input, size of buffer @e volume_key,
|
||||
* on output size of @e volume_key
|
||||
* on output size of @e volume_key in bytes
|
||||
* @param kc keyslot context used to unlock volume key
|
||||
*
|
||||
* @return unlocked key slot number or negative errno otherwise.
|
||||
@@ -1881,7 +1925,7 @@ int crypt_volume_key_get_by_keyslot_context(struct crypt_device *cd,
|
||||
*
|
||||
* @param cd crypt device handle
|
||||
* @param volume_key provided volume key
|
||||
* @param volume_key_size size of @e volume_key
|
||||
* @param volume_key_size size of @e volume_key in bytes
|
||||
*
|
||||
* @return @e 0 on success or negative errno value otherwise.
|
||||
*
|
||||
@@ -2023,6 +2067,19 @@ uint64_t crypt_get_iv_offset(struct crypt_device *cd);
|
||||
*/
|
||||
int crypt_get_volume_key_size(struct crypt_device *cd);
|
||||
|
||||
/**
|
||||
* Get size (in bytes) of old volume key for LUKS2 device in reencryption.
|
||||
*
|
||||
* @param cd crypt LUKS2 device handle
|
||||
*
|
||||
* @return old volume key size when device is in reencryption state
|
||||
*
|
||||
* @note For LUKS2, this function can be used only if there is at least
|
||||
* one keyslot assigned to old data segment. Also with reencryption
|
||||
* mode 'encrypt' there's no old volume key.
|
||||
*/
|
||||
int crypt_get_old_volume_key_size(struct crypt_device *cd);
|
||||
|
||||
/**
|
||||
* Get size (in bytes) of encryption sector for crypt device.
|
||||
*
|
||||
@@ -2060,6 +2117,18 @@ int crypt_header_is_detached(struct crypt_device *cd);
|
||||
int crypt_get_verity_info(struct crypt_device *cd,
|
||||
struct crypt_params_verity *vp);
|
||||
|
||||
/**
|
||||
* Get FEC repaired block count for VERITY device.
|
||||
*
|
||||
* @param cd crypt device handle
|
||||
* @param name verity device name
|
||||
* @param repaired FEC repaired blocks
|
||||
*
|
||||
* @return @e 0 on success or negative errno value otherwise.
|
||||
*/
|
||||
int crypt_get_verity_repaired(struct crypt_device *cd, const char *name,
|
||||
uint64_t *repaired);
|
||||
|
||||
/**
|
||||
* Get device parameters for INTEGRITY device.
|
||||
*
|
||||
@@ -2115,7 +2184,7 @@ int crypt_benchmark(struct crypt_device *cd,
|
||||
* @param password_size size of password
|
||||
* @param salt salt for benchmark
|
||||
* @param salt_size size of salt
|
||||
* @param volume_key_size output volume key size
|
||||
* @param volume_key_size output volume key size in bytes
|
||||
* @param progress callback function
|
||||
* @param usrptr provided identification in callback
|
||||
*
|
||||
@@ -2352,8 +2421,8 @@ void crypt_set_debug_level(int level);
|
||||
* @param cd crypt device handle
|
||||
* @param keyfile keyfile to read
|
||||
* @param key buffer for key
|
||||
* @param key_size_read size of read key
|
||||
* @param keyfile_offset key offset in keyfile
|
||||
* @param key_size_read size of read key in bytes
|
||||
* @param keyfile_offset key offset in bytes in keyfile
|
||||
* @param key_size exact key length to read from file or 0
|
||||
* @param flags keyfile read flags
|
||||
*
|
||||
@@ -2431,7 +2500,6 @@ int crypt_wipe(struct crypt_device *cd,
|
||||
|
||||
/** Use direct-io */
|
||||
#define CRYPT_WIPE_NO_DIRECT_IO (UINT32_C(1) << 0)
|
||||
/** @} */
|
||||
|
||||
enum {
|
||||
CRYPT_LUKS2_SEGMENT = -2,
|
||||
@@ -2462,6 +2530,8 @@ int crypt_wipe_hw_opal(struct crypt_device *cd,
|
||||
uint32_t flags /* currently unused */
|
||||
);
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @defgroup crypt-tokens LUKS2 token wrapper access
|
||||
*
|
||||
@@ -2593,11 +2663,11 @@ int crypt_token_luks2_keyring_get(struct crypt_device *cd,
|
||||
* (There can be more keyslots assigned to one token id.)
|
||||
*
|
||||
* @param cd crypt device handle
|
||||
* @param token token id
|
||||
* @param token specific token id
|
||||
* @param keyslot keyslot to be assigned to token (CRYPT_ANY SLOT
|
||||
* assigns all active keyslots to token)
|
||||
*
|
||||
* @return allocated token id or negative errno otherwise.
|
||||
* @return requested token id to be assigned or negative errno otherwise.
|
||||
*/
|
||||
int crypt_token_assign_keyslot(struct crypt_device *cd,
|
||||
int token,
|
||||
@@ -2608,11 +2678,11 @@ int crypt_token_assign_keyslot(struct crypt_device *cd,
|
||||
* (There can be more keyslots assigned to one token id.)
|
||||
*
|
||||
* @param cd crypt device handle
|
||||
* @param token token id
|
||||
* @param token specific token id
|
||||
* @param keyslot keyslot to be unassigned from token (CRYPT_ANY SLOT
|
||||
* unassigns all active keyslots from token)
|
||||
*
|
||||
* @return allocated token id or negative errno otherwise.
|
||||
* @return requested token id to be unassigned or negative errno otherwise.
|
||||
*/
|
||||
int crypt_token_unassign_keyslot(struct crypt_device *cd,
|
||||
int token,
|
||||
@@ -2897,6 +2967,12 @@ int crypt_activate_by_token_pin(struct crypt_device *cd,
|
||||
#define CRYPT_REENCRYPT_RECOVERY (UINT32_C(1) << 3)
|
||||
/** Reencryption requires metadata protection. (in/out) */
|
||||
#define CRYPT_REENCRYPT_REPAIR_NEEDED (UINT32_C(1) << 4)
|
||||
/**
|
||||
* Calculate new (future) volume key digest directly during
|
||||
* reencryption initialization. The keyslot context for new
|
||||
* volume key must be CRYPT_KC_TYPE_KEY or
|
||||
* CRYPT_KC_TYPE_VK_KEYRING. (in) */
|
||||
#define CRYPT_REENCRYPT_CREATE_NEW_DIGEST (UINT32_C(1) << 5)
|
||||
|
||||
/**
|
||||
* Reencryption direction
|
||||
@@ -2993,6 +3069,71 @@ int crypt_reencrypt_init_by_keyring(struct crypt_device *cd,
|
||||
const char *cipher_mode,
|
||||
const struct crypt_params_reencrypt *params);
|
||||
|
||||
/**
|
||||
*
|
||||
* Initialize or reload LUKS2 reencryption operation using keyslot contexts.
|
||||
*
|
||||
* The function can initialize reencryption on-disk metadata or reload reencryption
|
||||
* context from on-disk LUSK2 metadata to resume interrupted operation.
|
||||
*
|
||||
* If the device is not in reencryption state (@link crypt_reencrypt_status @endlink
|
||||
* returns @link CRYPT_REENCRYPT_NONE @endlink) the function initializes on-disk
|
||||
* metadata to include all necessary reencryption segments and new encryption
|
||||
* parameters (cipher, cipher mode, encryption sector size) according to the
|
||||
* provided parameters.
|
||||
*
|
||||
* If on-disk metadata already describes reencryption operation
|
||||
* (@link crypt_reencrypt_status @endlink returns @link CRYPT_REENCRYPT_CLEAN @endlink),
|
||||
* it loads these parameters and internally initializes reencryption context. It also verifies
|
||||
* if the device is eligible to resume reencryption operation. Some reencryption parameters
|
||||
* (@link crypt_params_reencrypt @endlink) may be modified depending on the original values in
|
||||
* the initialization call. When resuming the operation, all parameters may be omitted except
|
||||
* @e cd, @e name (offline/online),@e kc_old and @e kc_new.
|
||||
*
|
||||
* If on-disk metadata describes reencryption operation requiring recovery
|
||||
* (@link crypt_reencrypt_status @endlink returns @link CRYPT_REENCRYPT_CRASH @endlink),
|
||||
* it can be recovered by adding @link CRYPT_REENCRYPT_RECOVERY @endlink flag in @link
|
||||
* crypt_params_reencrypt @endlink parameter.
|
||||
*
|
||||
* @param cd crypt device handle
|
||||
* @param name name of the active device or @e NULL for offline reencryption
|
||||
* @param kc_old keyslot context providing access to volume key in keyslot id @e keyslot_old.
|
||||
* @param kc_new keyslot context providing access to volume key in keyslot id @e keyslot_new.
|
||||
* @param keyslot_old keyslot id containing current volume key for the device or CRYPT_ANY_SLOT
|
||||
* @param keyslot_new keyslot id containing (unbound) future volume key in encryption or reencryption
|
||||
* operation. It must be set in the initialization call except when initializing the decrypt
|
||||
* operation. In reencryption operation it may contain also the current volume key in case the
|
||||
* volume key change is not requested.
|
||||
* @param cipher new cipher specification (e.g. "aes") or @e NULL in decryption. Relevant only
|
||||
* during metadata initialization.
|
||||
* @param cipher_mode cipher mode and IV (e.g. "xts-plain64") or @e NULL in decryption.
|
||||
* Relevant only during metadata initialization.
|
||||
* @param params reencryption parameters @link crypt_params_reencrypt @endlink.
|
||||
*
|
||||
* @return reencryption key slot number or negative errno otherwise.
|
||||
*
|
||||
* @note Only after successful reencryption initialization you may run the operation with
|
||||
* @link crypt_reencrypt_run @endlink.
|
||||
*
|
||||
* @note During @link CRYPT_REENCRYPT_REENCRYPT @endlink operation it is highly recommended
|
||||
* to use same keyslot context (same passphrase, token, keyfile, etc) in both @e kc_old
|
||||
* and @e kc_new parameters for at least one keyslot containing future volume key and one
|
||||
* keyslot containing current volume key. If the same keyslot context can not be used
|
||||
* to unlock any current or any future volume key it would be impossible to perform reencryption
|
||||
* crash recovery during device activation for example after system reboot. Any keyslot
|
||||
* passphrase may be changed in-before initializing reencryption operation via @link
|
||||
* crypt_keyslot_change_by_passphrase @endlink.
|
||||
*/
|
||||
int crypt_reencrypt_init_by_keyslot_context(struct crypt_device *cd,
|
||||
const char *name,
|
||||
struct crypt_keyslot_context *kc_old,
|
||||
struct crypt_keyslot_context *kc_new,
|
||||
int keyslot_old,
|
||||
int keyslot_new,
|
||||
const char *cipher,
|
||||
const char *cipher_mode,
|
||||
const struct crypt_params_reencrypt *params);
|
||||
|
||||
/**
|
||||
* Legacy data reencryption function.
|
||||
*
|
||||
@@ -3017,6 +3158,8 @@ __attribute__((deprecated));
|
||||
* @param usrptr progress specific data
|
||||
*
|
||||
* @return @e 0 on success or negative errno value otherwise.
|
||||
*
|
||||
* @note A @e progress callback can interrupt reencryption process by returning non-zero code.
|
||||
*/
|
||||
int crypt_reencrypt_run(struct crypt_device *cd,
|
||||
int (*progress)(uint64_t size, uint64_t offset, void *usrptr),
|
||||
@@ -3085,19 +3228,51 @@ void *crypt_safe_realloc(void *data, size_t size);
|
||||
*/
|
||||
void crypt_safe_memzero(void *data, size_t size);
|
||||
|
||||
/**
|
||||
* Memcpy helper to avoid spilling sensitive data through additional registers
|
||||
*
|
||||
* @param dst pointer to memory to be written
|
||||
* @param src pointer to memory to be copied
|
||||
* @param size size of memory in bytes
|
||||
*/
|
||||
void *crypt_safe_memcpy(void *dst, const void *src, size_t size);
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @defgroup crypt-keyring Kernel keyring manipulation
|
||||
* @addtogroup crypt-keyring
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Link the volume key to the specified kernel keyring.
|
||||
*
|
||||
* The volume can have one or two keys. Normally, the device has one key.
|
||||
* However if reencryption was started and not finished yet, the volume will
|
||||
* have two volume keys (the new VK for the already reencrypted segment and old
|
||||
* VK for the not yet reencrypted segment).
|
||||
*
|
||||
* The @e old_key_description argument is required only for
|
||||
* devices that are in re-encryption and have two volume keys at the same time
|
||||
* (old and new). You can set the @e old_key_description to NULL,
|
||||
* but if you supply number of keys less than required, the function will
|
||||
* return -ESRCH. In that case you need to call the function again and set
|
||||
* the missing key description. When supplying just one key description, make
|
||||
* sure to supply it in the @e key_description.
|
||||
*
|
||||
* @param cd crypt device handle
|
||||
* @param key_description the key description of volume key linked in desired keyring.
|
||||
* @param key_type the key type used for the volume key. Currently only "user" and "logon" types are
|
||||
* @param key_description the key description of the volume key linked in desired keyring.
|
||||
* @param old_key_description the key description of the old volume key linked in desired keyring
|
||||
* (for devices in re-encryption).
|
||||
* @param key_type_desc the key type used for the volume key. Currently only "user" and "logon" types are
|
||||
* supported. if @e NULL is specified the default "user" type is applied.
|
||||
* @param keyring_to_link_vk the keyring description of the keyring in which volume key should
|
||||
* be linked, if @e NULL is specified, linking will be disabled.
|
||||
*
|
||||
* @note keyring_to_link_vk may be passed in various string formats:
|
||||
* It can be kernel key numeric id of existing keyring written as a string,
|
||||
* keyring name prefixed optionally be either "%:" or "%keyring:" substrings or keyctl
|
||||
* keyring name prefixed by either "%:" or "%keyring:" substrings or keyctl
|
||||
* special values for keyrings "@t", "@p", "@s" and so on. See keyctl(1) man page,
|
||||
* section KEY IDENTIFIERS for more information. All other prefixes starting "%<type>:"
|
||||
* are ignored.
|
||||
@@ -3105,8 +3280,11 @@ void crypt_safe_memzero(void *data, size_t size);
|
||||
* @note key_description "%<type>:" prefixes are ignored. Type is applied based on key_type parameter
|
||||
* value.
|
||||
*/
|
||||
int crypt_set_keyring_to_link(struct crypt_device *cd, const char *key_description,
|
||||
const char *key_type_desc, const char *keyring_to_link_vk);
|
||||
int crypt_set_keyring_to_link(struct crypt_device* cd,
|
||||
const char* key_description,
|
||||
const char* old_key_description,
|
||||
const char* key_type_desc,
|
||||
const char* keyring_to_link_vk);
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
@@ -180,3 +180,23 @@ CRYPTSETUP_2.7 {
|
||||
crypt_set_keyring_to_link;
|
||||
crypt_wipe_hw_opal;
|
||||
} CRYPTSETUP_2.6;
|
||||
|
||||
CRYPTSETUP_2.8 {
|
||||
global:
|
||||
crypt_safe_memcpy;
|
||||
crypt_keyslot_context_init_by_passphrase;
|
||||
crypt_keyslot_context_init_by_keyfile;
|
||||
crypt_keyslot_context_init_by_token;
|
||||
crypt_keyslot_context_init_by_volume_key;
|
||||
crypt_keyslot_context_init_by_signed_key;
|
||||
crypt_keyslot_context_init_by_keyring;
|
||||
crypt_keyslot_context_init_by_vk_in_keyring;
|
||||
crypt_reencrypt_init_by_keyslot_context;
|
||||
crypt_get_old_volume_key_size;
|
||||
crypt_format_inline;
|
||||
} CRYPTSETUP_2.7;
|
||||
|
||||
CRYPTSETUP_2.9 {
|
||||
global:
|
||||
crypt_get_verity_repaired;
|
||||
} CRYPTSETUP_2.8;
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* Definitions of common constant and generic macros of libcryptsetup
|
||||
*
|
||||
* Copyright (C) 2009-2023 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2023 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* Copyright (C) 2009-2025 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2025 Milan Broz
|
||||
*/
|
||||
|
||||
#ifndef _LIBCRYPTSETUP_MACROS_H
|
||||
@@ -62,9 +49,17 @@
|
||||
#define DEFAULT_MEM_ALIGNMENT 4096
|
||||
|
||||
#define DM_UUID_LEN 129
|
||||
#define DM_NAME_LEN 128
|
||||
#define DM_BY_ID_PREFIX "dm-uuid-"
|
||||
#define DM_BY_ID_PREFIX_LEN 8
|
||||
#define DM_UUID_PREFIX "CRYPT-"
|
||||
#define DM_UUID_PREFIX_LEN 6
|
||||
|
||||
#define OPAL_PSID_LEN 32
|
||||
|
||||
/* LUKS AF stripes, never set to any other value than 4000 */
|
||||
#ifndef LUKS_STRIPES
|
||||
# define LUKS_STRIPES 4000
|
||||
#endif
|
||||
|
||||
#endif /* _LIBCRYPTSETUP_MACROS_H */
|
||||
|
||||
@@ -1,21 +1,8 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* Helpers for defining versioned symbols
|
||||
*
|
||||
* Copyright (C) 2021-2023 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
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* Copyright (C) 2021-2025 Red Hat, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _LIBCRYPTSETUP_SYMVER_H
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,22 +1,9 @@
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
/*
|
||||
* loop-AES compatible volume handling
|
||||
*
|
||||
* Copyright (C) 2011-2023 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2011-2023 Milan Broz
|
||||
*
|
||||
* 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.
|
||||
* Copyright (C) 2011-2025 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2011-2025 Milan Broz
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
@@ -82,6 +69,7 @@ static int hash_keys(struct crypt_device *cd,
|
||||
char tweak, *key_ptr;
|
||||
unsigned int i;
|
||||
int r = 0;
|
||||
void *key = NULL;
|
||||
|
||||
hash_name = hash_override ?: get_hash(key_len_output);
|
||||
tweak = get_tweak(keys_count);
|
||||
@@ -92,24 +80,30 @@ static int hash_keys(struct crypt_device *cd,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
*vk = crypt_alloc_volume_key((size_t)key_len_output * keys_count, NULL);
|
||||
if (!*vk)
|
||||
key = crypt_safe_alloc((size_t)key_len_output * keys_count);
|
||||
if (!key)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < keys_count; i++) {
|
||||
key_ptr = &(*vk)->key[i * key_len_output];
|
||||
key_ptr = &((char *)key)[i * key_len_output];
|
||||
r = hash_key(input_keys[i], key_len_input, key_ptr,
|
||||
key_len_output, hash_name);
|
||||
if (r < 0)
|
||||
break;
|
||||
goto err;
|
||||
|
||||
key_ptr[0] ^= tweak;
|
||||
}
|
||||
|
||||
if (r < 0 && *vk) {
|
||||
crypt_free_volume_key(*vk);
|
||||
*vk = NULL;
|
||||
*vk = crypt_alloc_volume_key_by_safe_alloc(&key);
|
||||
if (!*vk) {
|
||||
r = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
err:
|
||||
crypt_safe_free(key);
|
||||
*vk = NULL;
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -158,7 +152,7 @@ int LOOPAES_parse_keyfile(struct crypt_device *cd,
|
||||
key_lengths[0] = 0;
|
||||
while (offset < buffer_len && key_index < LOOPAES_KEYS_MAX) {
|
||||
keys[key_index] = &buffer[offset];
|
||||
key_lengths[key_index] = 0;;
|
||||
key_lengths[key_index] = 0;
|
||||
while (offset < buffer_len && buffer[offset]) {
|
||||
offset++;
|
||||
key_lengths[key_index]++;
|
||||
@@ -204,7 +198,7 @@ int LOOPAES_activate(struct crypt_device *cd,
|
||||
uint32_t flags)
|
||||
{
|
||||
int r;
|
||||
uint32_t req_flags, dmc_flags;
|
||||
uint64_t req_flags, dmc_flags;
|
||||
char *cipher = NULL;
|
||||
struct crypt_dm_active_device dmd = {
|
||||
.flags = flags,
|
||||
@@ -226,9 +220,8 @@ int LOOPAES_activate(struct crypt_device *cd,
|
||||
return -ENOMEM;
|
||||
|
||||
r = dm_crypt_target_set(&dmd.segment, 0, dmd.size, crypt_data_device(cd),
|
||||
vk, cipher, crypt_get_iv_offset(cd),
|
||||
crypt_get_data_offset(cd), crypt_get_integrity(cd),
|
||||
crypt_get_integrity_tag_size(cd), crypt_get_sector_size(cd));
|
||||
vk, cipher, crypt_get_iv_offset(cd), crypt_get_data_offset(cd),
|
||||
NULL, 0, 0, crypt_get_sector_size(cd));
|
||||
|
||||
if (r) {
|
||||
free(cipher);
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
/*
|
||||
* loop-AES compatible volume handling
|
||||
*
|
||||
* Copyright (C) 2011-2023 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2011-2023 Milan Broz
|
||||
*
|
||||
* 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.
|
||||
* Copyright (C) 2011-2025 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2011-2025 Milan Broz
|
||||
*/
|
||||
|
||||
#ifndef _LOOPAES_H
|
||||
|
||||
@@ -1,25 +1,12 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* AFsplitter - Anti forensic information splitter
|
||||
*
|
||||
* Copyright (C) 2004 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2023 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2025 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* AFsplitter diffuses information over a large stripe of data,
|
||||
* therefore supporting secure data destruction.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
@@ -1,26 +1,11 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* AFsplitter - Anti forensic information splitter
|
||||
*
|
||||
* Copyright (C) 2004 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2023 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* AFsplitter diffuses information over a large stripe of data,
|
||||
* therefore supporting secure data destruction.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* Copyright (C) 2009-2025 Red Hat, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_CRYPTSETUP_LUKS_AF_H
|
||||
#define INCLUDED_CRYPTSETUP_LUKS_AF_H
|
||||
|
||||
|
||||
@@ -1,23 +1,10 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* LUKS - Linux Unified Key Setup
|
||||
*
|
||||
* Copyright (C) 2004-2006 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2023 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2023 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* Copyright (C) 2009-2025 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2025 Milan Broz
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
@@ -101,7 +88,7 @@ static int LUKS_endec_template(char *src, size_t srcLength,
|
||||
|
||||
r = dm_crypt_target_set(&dmd.segment, 0, dmd.size,
|
||||
crypt_metadata_device(ctx), vk, cipher_spec, 0, sector,
|
||||
NULL, 0, SECTOR_SIZE);
|
||||
NULL, 0, 0, SECTOR_SIZE);
|
||||
if (r)
|
||||
goto out;
|
||||
|
||||
@@ -109,7 +96,7 @@ static int LUKS_endec_template(char *src, size_t srcLength,
|
||||
if (r < 0) {
|
||||
if (r != -EACCES && r != -ENOTSUP)
|
||||
_error_hint(ctx, device_path(crypt_metadata_device(ctx)),
|
||||
cipher, cipher_mode, vk->keylength * 8);
|
||||
cipher, cipher_mode, crypt_volume_key_length(vk) * 8);
|
||||
r = -EIO;
|
||||
goto out;
|
||||
}
|
||||
@@ -153,7 +140,8 @@ 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, false);
|
||||
r = crypt_storage_init(&s, SECTOR_SIZE, cipher, cipher_mode, crypt_volume_key_get_key(vk),
|
||||
crypt_volume_key_length(vk), false);
|
||||
|
||||
if (r)
|
||||
log_dbg(ctx, "Userspace crypto wrapper cannot use %s-%s (%d).",
|
||||
@@ -166,7 +154,7 @@ int LUKS_encrypt_to_storage(char *src, size_t srcLength,
|
||||
|
||||
if (r) {
|
||||
_error_hint(ctx, device_path(device), cipher, cipher_mode,
|
||||
vk->keylength * 8);
|
||||
crypt_volume_key_length(vk) * 8);
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -218,7 +206,8 @@ 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, false);
|
||||
r = crypt_storage_init(&s, SECTOR_SIZE, cipher, cipher_mode, crypt_volume_key_get_key(vk),
|
||||
crypt_volume_key_length(vk), false);
|
||||
|
||||
if (r)
|
||||
log_dbg(ctx, "Userspace crypto wrapper cannot use %s-%s (%d).",
|
||||
@@ -231,7 +220,7 @@ int LUKS_decrypt_from_storage(char *dst, size_t dstLength,
|
||||
|
||||
if (r) {
|
||||
_error_hint(ctx, device_path(device), cipher, cipher_mode,
|
||||
vk->keylength * 8);
|
||||
crypt_volume_key_length(vk) * 8);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,23 +1,10 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* LUKS - Linux Unified Key Setup
|
||||
*
|
||||
* Copyright (C) 2004-2006 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2023 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2013-2023 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* Copyright (C) 2009-2025 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2013-2025 Milan Broz
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
@@ -391,7 +378,7 @@ static int _keyslot_repair(struct luks_phdr *phdr, struct crypt_device *ctx)
|
||||
{
|
||||
struct luks_phdr temp_phdr;
|
||||
const unsigned char *sector = (const unsigned char*)phdr;
|
||||
struct volume_key *vk;
|
||||
struct volume_key *fake_vk;
|
||||
int i, bad, r, need_write = 0;
|
||||
|
||||
if (phdr->keyBytes != 16 && phdr->keyBytes != 32 && phdr->keyBytes != 64) {
|
||||
@@ -437,8 +424,8 @@ static int _keyslot_repair(struct luks_phdr *phdr, struct crypt_device *ctx)
|
||||
if (r < 0)
|
||||
return -EINVAL;
|
||||
|
||||
vk = crypt_alloc_volume_key(phdr->keyBytes, NULL);
|
||||
if (!vk)
|
||||
fake_vk = crypt_generate_volume_key(ctx, phdr->keyBytes, KEY_QUALITY_EMPTY);
|
||||
if (!fake_vk)
|
||||
return -ENOMEM;
|
||||
|
||||
log_verbose(ctx, _("Repairing keyslots."));
|
||||
@@ -446,7 +433,7 @@ static int _keyslot_repair(struct luks_phdr *phdr, struct crypt_device *ctx)
|
||||
log_dbg(ctx, "Generating second header with the same parameters for check.");
|
||||
/* cipherName, cipherMode, hashSpec, uuid are already null terminated */
|
||||
/* payloadOffset - cannot check */
|
||||
r = LUKS_generate_phdr(&temp_phdr, vk, phdr->cipherName, phdr->cipherMode,
|
||||
r = LUKS_generate_phdr(&temp_phdr, fake_vk, phdr->cipherName, phdr->cipherMode,
|
||||
phdr->hashSpec, phdr->uuid,
|
||||
phdr->payloadOffset * SECTOR_SIZE, 0, 0, ctx);
|
||||
if (r < 0)
|
||||
@@ -505,7 +492,7 @@ static int _keyslot_repair(struct luks_phdr *phdr, struct crypt_device *ctx)
|
||||
out:
|
||||
if (r)
|
||||
log_err(ctx, _("Repair failed."));
|
||||
crypt_free_volume_key(vk);
|
||||
crypt_free_volume_key(fake_vk);
|
||||
crypt_safe_memzero(&temp_phdr, sizeof(temp_phdr));
|
||||
return r;
|
||||
}
|
||||
@@ -723,14 +710,12 @@ int LUKS_check_cipher(struct crypt_device *ctx, size_t keylength, const char *ci
|
||||
|
||||
log_dbg(ctx, "Checking if cipher %s-%s is usable.", cipher, cipher_mode);
|
||||
|
||||
empty_key = crypt_alloc_volume_key(keylength, NULL);
|
||||
/* No need to get KEY quality random but it must avoid known weak keys. */
|
||||
empty_key = crypt_generate_volume_key(ctx, keylength, KEY_QUALITY_NORMAL);
|
||||
if (!empty_key)
|
||||
return -ENOMEM;
|
||||
|
||||
/* No need to get KEY quality random but it must avoid known weak keys. */
|
||||
r = crypt_random_get(ctx, empty_key->key, empty_key->keylength, CRYPT_RND_NORMAL);
|
||||
if (!r)
|
||||
r = LUKS_decrypt_from_storage(buf, sizeof(buf), cipher, cipher_mode, empty_key, 0, ctx);
|
||||
r = LUKS_decrypt_from_storage(buf, sizeof(buf), cipher, cipher_mode, empty_key, 0, ctx);
|
||||
|
||||
crypt_free_volume_key(empty_key);
|
||||
crypt_safe_memzero(buf, sizeof(buf));
|
||||
@@ -761,7 +746,7 @@ int LUKS_generate_phdr(struct luks_phdr *header,
|
||||
|
||||
memset(header, 0, sizeof(struct luks_phdr));
|
||||
|
||||
keyslot_sectors = AF_split_sectors(vk->keylength, LUKS_STRIPES);
|
||||
keyslot_sectors = AF_split_sectors(crypt_volume_key_length(vk), LUKS_STRIPES);
|
||||
header_sectors = LUKS_ALIGN_KEYSLOTS / SECTOR_SIZE;
|
||||
|
||||
for (i = 0; i < LUKS_NUMKEYS; i++) {
|
||||
@@ -808,7 +793,7 @@ int LUKS_generate_phdr(struct luks_phdr *header,
|
||||
strncpy(header->hashSpec,hashSpec,LUKS_HASHSPEC_L-1);
|
||||
_to_lower(header->hashSpec, LUKS_HASHSPEC_L);
|
||||
|
||||
header->keyBytes=vk->keylength;
|
||||
header->keyBytes = crypt_volume_key_length(vk);
|
||||
|
||||
log_dbg(ctx, "Generating LUKS header version %d using hash %s, %s, %s, MK %d bytes",
|
||||
header->version, header->hashSpec ,header->cipherName, header->cipherMode,
|
||||
@@ -822,7 +807,7 @@ int LUKS_generate_phdr(struct luks_phdr *header,
|
||||
|
||||
/* Compute volume key digest */
|
||||
pbkdf = crypt_get_pbkdf(ctx);
|
||||
r = crypt_benchmark_pbkdf_internal(ctx, pbkdf, vk->keylength);
|
||||
r = crypt_benchmark_pbkdf_internal(ctx, pbkdf, crypt_volume_key_length(vk));
|
||||
if (r < 0)
|
||||
return r;
|
||||
assert(pbkdf->iterations);
|
||||
@@ -837,7 +822,9 @@ int LUKS_generate_phdr(struct luks_phdr *header,
|
||||
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,
|
||||
r = crypt_pbkdf(CRYPT_KDF_PBKDF2, header->hashSpec,
|
||||
crypt_volume_key_get_key(vk),
|
||||
crypt_volume_key_length(vk),
|
||||
header->mkDigestSalt, LUKS_SALTSIZE,
|
||||
header->mkDigest,LUKS_DIGESTSIZE,
|
||||
header->mkDigestIterations, 0, 0);
|
||||
@@ -879,8 +866,9 @@ int LUKS_set_key(unsigned int keyIndex,
|
||||
struct luks_phdr *hdr, struct volume_key *vk,
|
||||
struct crypt_device *ctx)
|
||||
{
|
||||
struct volume_key *derived_key;
|
||||
struct volume_key *derived_vk = NULL;
|
||||
char *AfKey = NULL;
|
||||
void *derived_key = NULL;
|
||||
size_t AFEKSize;
|
||||
struct crypt_pbkdf_type *pbkdf;
|
||||
int r;
|
||||
@@ -899,7 +887,7 @@ int LUKS_set_key(unsigned int keyIndex,
|
||||
|
||||
log_dbg(ctx, "Calculating data for key slot %d", keyIndex);
|
||||
pbkdf = crypt_get_pbkdf(ctx);
|
||||
r = crypt_benchmark_pbkdf_internal(ctx, pbkdf, vk->keylength);
|
||||
r = crypt_benchmark_pbkdf_internal(ctx, pbkdf, crypt_volume_key_length(vk));
|
||||
if (r < 0)
|
||||
return r;
|
||||
assert(pbkdf->iterations);
|
||||
@@ -912,9 +900,11 @@ int LUKS_set_key(unsigned int keyIndex,
|
||||
log_dbg(ctx, "Key slot %d use %" PRIu32 " password iterations.", keyIndex,
|
||||
hdr->keyblock[keyIndex].passwordIterations);
|
||||
|
||||
derived_key = crypt_alloc_volume_key(hdr->keyBytes, NULL);
|
||||
if (!derived_key)
|
||||
return -ENOMEM;
|
||||
derived_key = crypt_safe_alloc(hdr->keyBytes);
|
||||
if (!derived_key) {
|
||||
r = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
r = crypt_random_get(ctx, hdr->keyblock[keyIndex].passwordSalt,
|
||||
LUKS_SALTSIZE, CRYPT_RND_SALT);
|
||||
@@ -923,7 +913,7 @@ int LUKS_set_key(unsigned int keyIndex,
|
||||
|
||||
r = crypt_pbkdf(CRYPT_KDF_PBKDF2, hdr->hashSpec, password, passwordLen,
|
||||
hdr->keyblock[keyIndex].passwordSalt, LUKS_SALTSIZE,
|
||||
derived_key->key, hdr->keyBytes,
|
||||
derived_key, hdr->keyBytes,
|
||||
hdr->keyblock[keyIndex].passwordIterations, 0, 0);
|
||||
if (r < 0) {
|
||||
if ((crypt_backend_flags() & CRYPT_BACKEND_PBKDF2_INT) &&
|
||||
@@ -932,11 +922,17 @@ int LUKS_set_key(unsigned int keyIndex,
|
||||
goto out;
|
||||
}
|
||||
|
||||
derived_vk = crypt_alloc_volume_key_by_safe_alloc(&derived_key);
|
||||
if (!derived_vk) {
|
||||
r = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* AF splitting, the volume key stored in vk->key is split to AfKey
|
||||
*/
|
||||
assert(vk->keylength == hdr->keyBytes);
|
||||
AFEKSize = AF_split_sectors(vk->keylength, hdr->keyblock[keyIndex].stripes) * SECTOR_SIZE;
|
||||
assert(crypt_volume_key_length(vk) == hdr->keyBytes);
|
||||
AFEKSize = AF_split_sectors(crypt_volume_key_length(vk), hdr->keyblock[keyIndex].stripes) * SECTOR_SIZE;
|
||||
AfKey = crypt_safe_alloc(AFEKSize);
|
||||
if (!AfKey) {
|
||||
r = -ENOMEM;
|
||||
@@ -945,7 +941,8 @@ int LUKS_set_key(unsigned int keyIndex,
|
||||
|
||||
log_dbg(ctx, "Using hash %s for AF in key slot %d, %d stripes",
|
||||
hdr->hashSpec, keyIndex, hdr->keyblock[keyIndex].stripes);
|
||||
r = AF_split(ctx, vk->key, AfKey, vk->keylength, hdr->keyblock[keyIndex].stripes, hdr->hashSpec);
|
||||
r = AF_split(ctx, crypt_volume_key_get_key(vk), AfKey, crypt_volume_key_length(vk),
|
||||
hdr->keyblock[keyIndex].stripes, hdr->hashSpec);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
|
||||
@@ -955,7 +952,7 @@ int LUKS_set_key(unsigned int keyIndex,
|
||||
r = LUKS_encrypt_to_storage(AfKey,
|
||||
AFEKSize,
|
||||
hdr->cipherName, hdr->cipherMode,
|
||||
derived_key,
|
||||
derived_vk,
|
||||
hdr->keyblock[keyIndex].keyMaterialOffset,
|
||||
ctx);
|
||||
if (r < 0)
|
||||
@@ -973,7 +970,8 @@ int LUKS_set_key(unsigned int keyIndex,
|
||||
r = 0;
|
||||
out:
|
||||
crypt_safe_free(AfKey);
|
||||
crypt_free_volume_key(derived_key);
|
||||
crypt_safe_free(derived_key);
|
||||
crypt_free_volume_key(derived_vk);
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -983,7 +981,8 @@ int LUKS_verify_volume_key(const struct luks_phdr *hdr,
|
||||
{
|
||||
char checkHashBuf[LUKS_DIGESTSIZE];
|
||||
|
||||
if (crypt_pbkdf(CRYPT_KDF_PBKDF2, hdr->hashSpec, vk->key, vk->keylength,
|
||||
if (crypt_pbkdf(CRYPT_KDF_PBKDF2, hdr->hashSpec, crypt_volume_key_get_key(vk),
|
||||
crypt_volume_key_length(vk),
|
||||
hdr->mkDigestSalt, LUKS_SALTSIZE,
|
||||
checkHashBuf, LUKS_DIGESTSIZE,
|
||||
hdr->mkDigestIterations, 0, 0) < 0)
|
||||
@@ -1000,12 +999,13 @@ 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 **r_vk,
|
||||
struct crypt_device *ctx)
|
||||
{
|
||||
crypt_keyslot_info ki = LUKS_keyslot_info(hdr, keyIndex);
|
||||
struct volume_key *derived_key;
|
||||
struct volume_key *derived_vk = NULL, *vk = NULL;
|
||||
char *AfKey = NULL;
|
||||
void *key = NULL, *derived_key = NULL;
|
||||
size_t AFEKSize;
|
||||
int r;
|
||||
|
||||
@@ -1015,12 +1015,12 @@ static int LUKS_open_key(unsigned int keyIndex,
|
||||
if (ki < CRYPT_SLOT_ACTIVE)
|
||||
return -ENOENT;
|
||||
|
||||
derived_key = crypt_alloc_volume_key(hdr->keyBytes, NULL);
|
||||
derived_key = crypt_safe_alloc(hdr->keyBytes);
|
||||
if (!derived_key)
|
||||
return -ENOMEM;
|
||||
|
||||
*vk = crypt_alloc_volume_key(hdr->keyBytes, NULL);
|
||||
if (!*vk) {
|
||||
key = crypt_safe_alloc(hdr->keyBytes);
|
||||
if (!key) {
|
||||
r = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
@@ -1034,39 +1034,57 @@ static int LUKS_open_key(unsigned int keyIndex,
|
||||
|
||||
r = crypt_pbkdf(CRYPT_KDF_PBKDF2, hdr->hashSpec, password, passwordLen,
|
||||
hdr->keyblock[keyIndex].passwordSalt, LUKS_SALTSIZE,
|
||||
derived_key->key, hdr->keyBytes,
|
||||
derived_key, hdr->keyBytes,
|
||||
hdr->keyblock[keyIndex].passwordIterations, 0, 0);
|
||||
if (r < 0) {
|
||||
log_err(ctx, _("Cannot open keyslot (using hash %s)."), hdr->hashSpec);
|
||||
goto out;
|
||||
}
|
||||
|
||||
derived_vk = crypt_alloc_volume_key_by_safe_alloc(&derived_key);
|
||||
if (!derived_vk) {
|
||||
r = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
log_dbg(ctx, "Reading key slot %d area.", keyIndex);
|
||||
r = LUKS_decrypt_from_storage(AfKey,
|
||||
AFEKSize,
|
||||
hdr->cipherName, hdr->cipherMode,
|
||||
derived_key,
|
||||
derived_vk,
|
||||
hdr->keyblock[keyIndex].keyMaterialOffset,
|
||||
ctx);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
|
||||
r = AF_merge(AfKey, (*vk)->key, (*vk)->keylength, hdr->keyblock[keyIndex].stripes, hdr->hashSpec);
|
||||
r = AF_merge(AfKey, key, hdr->keyBytes, hdr->keyblock[keyIndex].stripes, hdr->hashSpec);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
|
||||
r = LUKS_verify_volume_key(hdr, *vk);
|
||||
vk = crypt_alloc_volume_key_by_safe_alloc(&key);
|
||||
if (!vk) {
|
||||
r = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
r = LUKS_verify_volume_key(hdr, vk);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
|
||||
/* Allow only empty passphrase with null cipher */
|
||||
if (!r && crypt_is_cipher_null(hdr->cipherName) && passwordLen)
|
||||
if (crypt_is_cipher_null(hdr->cipherName) && passwordLen)
|
||||
r = -EPERM;
|
||||
else
|
||||
*r_vk = vk;
|
||||
out:
|
||||
if (r < 0) {
|
||||
crypt_free_volume_key(*vk);
|
||||
*vk = NULL;
|
||||
crypt_free_volume_key(vk);
|
||||
*r_vk = NULL;
|
||||
}
|
||||
crypt_safe_free(AfKey);
|
||||
crypt_free_volume_key(derived_key);
|
||||
crypt_safe_free(key);
|
||||
crypt_safe_free(derived_key);
|
||||
crypt_free_volume_key(derived_vk);
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -1217,8 +1235,7 @@ int LUKS1_activate(struct crypt_device *cd,
|
||||
|
||||
r = dm_crypt_target_set(&dmd.segment, 0, dmd.size, crypt_data_device(cd),
|
||||
vk, crypt_get_cipher_spec(cd), crypt_get_iv_offset(cd),
|
||||
crypt_get_data_offset(cd), crypt_get_integrity(cd),
|
||||
crypt_get_integrity_tag_size(cd), crypt_get_sector_size(cd));
|
||||
crypt_get_data_offset(cd), NULL, 0, 0, crypt_get_sector_size(cd));
|
||||
if (!r)
|
||||
r = create_or_reload_device(cd, name, CRYPT_LUKS1, &dmd);
|
||||
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* LUKS - Linux Unified Key Setup
|
||||
*
|
||||
* Copyright (C) 2004-2006 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2023 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
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* Copyright (C) 2009-2025 Red Hat, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_CRYPTSETUP_LUKS_LUKS_H
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,22 +1,10 @@
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
/*
|
||||
* OPAL utilities
|
||||
*
|
||||
* Copyright (C) 2022-2023 Luca Boccassi <bluca@debian.org>
|
||||
* 2023 Ondrej Kozina <okozina@redhat.com>
|
||||
*
|
||||
* 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.
|
||||
* Copyright (C) 2023-2025 Ondrej Kozina <okozina@redhat.com>
|
||||
* Copyright (C) 2024-2025 Milan Broz
|
||||
*/
|
||||
|
||||
#ifndef _UTILS_OPAL
|
||||
@@ -24,11 +12,14 @@
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
struct crypt_lock_handle;
|
||||
|
||||
int opal_setup_ranges(struct crypt_device *cd,
|
||||
struct device *dev,
|
||||
const struct volume_key *vk,
|
||||
uint64_t range_start,
|
||||
uint64_t range_length,
|
||||
uint64_t range_start_blocks,
|
||||
uint64_t range_length_blocks,
|
||||
uint32_t opal_block_bytes,
|
||||
uint32_t segment_number,
|
||||
const void *admin_key,
|
||||
size_t admin_key_len);
|
||||
@@ -38,7 +29,6 @@ int opal_unlock(struct crypt_device *cd,
|
||||
uint32_t segment_number,
|
||||
const struct volume_key *vk);
|
||||
int opal_supported(struct crypt_device *cd, struct device *dev);
|
||||
int opal_enabled(struct crypt_device *cd, struct device *dev);
|
||||
int opal_factory_reset(struct crypt_device *cd,
|
||||
struct device *dev,
|
||||
const char *password,
|
||||
@@ -54,13 +44,17 @@ int opal_geometry(struct crypt_device *cd,
|
||||
uint32_t *ret_block_size,
|
||||
uint64_t *ret_alignment_granularity_blocks,
|
||||
uint64_t *ret_lowest_lba_blocks);
|
||||
int opal_range_check_attributes(struct crypt_device *cd,
|
||||
int opal_range_check_attributes_and_get_lock_state(struct crypt_device *cd,
|
||||
struct device *dev,
|
||||
uint32_t segment_number,
|
||||
const struct volume_key *vk,
|
||||
const uint64_t *check_offset_sectors,
|
||||
const uint64_t *check_length_sectors,
|
||||
bool *check_read_locked,
|
||||
bool *check_write_locked);
|
||||
bool *ret_read_locked,
|
||||
bool *ret_write_locked);
|
||||
int opal_exclusive_lock(struct crypt_device *cd,
|
||||
struct device *opal_device,
|
||||
struct crypt_lock_handle **opal_lock);
|
||||
void opal_exclusive_unlock(struct crypt_device *cd, struct crypt_lock_handle *opal_lock);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* LUKS - Linux Unified Key Setup v2
|
||||
*
|
||||
* Copyright (C) 2015-2023 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2023 Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* Copyright (C) 2015-2025 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2015-2025 Milan Broz
|
||||
*/
|
||||
|
||||
#ifndef _CRYPTSETUP_LUKS2_ONDISK_H
|
||||
@@ -50,6 +37,8 @@
|
||||
|
||||
#define LUKS2_DIGEST_MAX 8
|
||||
|
||||
#define LUKS2_MIN_INTEGRITY_KEY_BYTES 16
|
||||
|
||||
#define CRYPT_ANY_SEGMENT -1
|
||||
#define CRYPT_DEFAULT_SEGMENT -2
|
||||
#define CRYPT_ONE_SEGMENT -3
|
||||
@@ -122,6 +111,7 @@ struct luks2_hdr {
|
||||
char uuid[LUKS2_UUID_L];
|
||||
void *jobj;
|
||||
void *jobj_rollback;
|
||||
size_t on_disk_json_end_offset;
|
||||
};
|
||||
|
||||
struct luks2_keyslot_params {
|
||||
@@ -158,6 +148,8 @@ struct luks2_keyslot_params {
|
||||
|
||||
#define LUKS2_HDR_OFFSET_MAX 0x400000 /* 4 MiB */
|
||||
|
||||
#define LUKS2_HDR_MAX_MDA_SIZE 2 * LUKS2_HDR_OFFSET_MAX + LUKS2_MAX_KEYSLOTS_SIZE
|
||||
|
||||
/* Offsets for secondary header (for scan if primary header is corrupted). */
|
||||
#define LUKS2_HDR2_OFFSETS { 0x04000, 0x008000, 0x010000, 0x020000, \
|
||||
0x40000, 0x080000, 0x100000, 0x200000, LUKS2_HDR_OFFSET_MAX }
|
||||
@@ -207,11 +199,11 @@ int LUKS2_keyslot_open(struct crypt_device *cd,
|
||||
size_t password_len,
|
||||
struct volume_key **vk);
|
||||
|
||||
int LUKS2_keyslot_open_all_segments(struct crypt_device *cd,
|
||||
int LUKS2_keyslot_context_open_all_segments(struct crypt_device *cd,
|
||||
int keyslot_old,
|
||||
int keyslot_new,
|
||||
const char *password,
|
||||
size_t password_len,
|
||||
struct crypt_keyslot_context *kc_old,
|
||||
struct crypt_keyslot_context *kc_new,
|
||||
struct volume_key **vks);
|
||||
|
||||
int LUKS2_keyslot_store(struct crypt_device *cd,
|
||||
@@ -239,6 +231,24 @@ int LUKS2_keyslot_swap(struct crypt_device *cd,
|
||||
int keyslot,
|
||||
int keyslot2);
|
||||
|
||||
/*
|
||||
* Segments
|
||||
*/
|
||||
|
||||
bool LUKS2_segment_set_size(struct luks2_hdr *hdr,
|
||||
int segment,
|
||||
const uint64_t *segment_size_bytes);
|
||||
|
||||
bool LUKS2_segment_is_hw_opal(struct luks2_hdr *hdr, int segment);
|
||||
bool LUKS2_segment_is_hw_opal_crypt(struct luks2_hdr *hdr, int segment);
|
||||
bool LUKS2_segment_is_hw_opal_only(struct luks2_hdr *hdr, int segment);
|
||||
|
||||
int LUKS2_get_opal_segment_number(struct luks2_hdr *hdr, int segment,
|
||||
uint32_t *ret_opal_segment_number);
|
||||
int LUKS2_get_opal_key_size(struct luks2_hdr *hdr, int segment);
|
||||
|
||||
bool LUKS2_segments_dynamic_size(struct luks2_hdr *hdr);
|
||||
|
||||
/*
|
||||
* Generic LUKS2 token
|
||||
*/
|
||||
@@ -274,17 +284,6 @@ crypt_token_info LUKS2_token_status(struct crypt_device *cd,
|
||||
int token,
|
||||
const char **type);
|
||||
|
||||
int LUKS2_token_open_and_activate(struct crypt_device *cd,
|
||||
struct luks2_hdr *hdr,
|
||||
int keyslot,
|
||||
int token,
|
||||
const char *name,
|
||||
const char *type,
|
||||
const char *pin,
|
||||
size_t pin_size,
|
||||
uint32_t flags,
|
||||
void *usrptr);
|
||||
|
||||
int LUKS2_token_unlock_key(struct crypt_device *cd,
|
||||
struct luks2_hdr *hdr,
|
||||
int keyslot,
|
||||
@@ -318,8 +317,7 @@ void crypt_token_unload_external_all(struct crypt_device *cd);
|
||||
/*
|
||||
* Generic LUKS2 digest
|
||||
*/
|
||||
int LUKS2_digest_any_matching(struct crypt_device *cd,
|
||||
struct luks2_hdr *hdr,
|
||||
int LUKS2_digest_verify_by_any_matching(struct crypt_device *cd,
|
||||
const struct volume_key *vk);
|
||||
|
||||
int LUKS2_digest_verify_by_segment(struct crypt_device *cd,
|
||||
@@ -382,6 +380,7 @@ int LUKS2_generate_hdr(
|
||||
const struct volume_key *vk,
|
||||
const char *cipher_spec,
|
||||
const char *integrity,
|
||||
uint32_t integrity_key_size, /* in bytes, only if separate (HMAC) */
|
||||
const char *uuid,
|
||||
unsigned int sector_size,
|
||||
uint64_t data_offset,
|
||||
@@ -402,15 +401,17 @@ 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, bool detached_header);
|
||||
struct luks2_hdr *hdr);
|
||||
|
||||
uint64_t LUKS2_get_data_offset(struct luks2_hdr *hdr);
|
||||
int LUKS2_get_data_size(struct luks2_hdr *hdr, uint64_t *size, bool *dynamic);
|
||||
uint32_t LUKS2_get_sector_size(struct luks2_hdr *hdr);
|
||||
const char *LUKS2_get_cipher(struct luks2_hdr *hdr, int segment);
|
||||
const char *LUKS2_get_integrity(struct luks2_hdr *hdr, int segment);
|
||||
int LUKS2_get_integrity_key_size(struct luks2_hdr *hdr, int segment);
|
||||
int LUKS2_keyslot_params_default(struct crypt_device *cd, struct luks2_hdr *hdr,
|
||||
struct luks2_keyslot_params *params);
|
||||
int LUKS2_get_old_volume_key_size(struct luks2_hdr *hdr);
|
||||
int LUKS2_get_volume_key_size(struct luks2_hdr *hdr, int segment);
|
||||
int LUKS2_get_keyslot_stored_key_size(struct luks2_hdr *hdr, int keyslot);
|
||||
const char *LUKS2_get_keyslot_cipher(struct luks2_hdr *hdr, int keyslot, size_t *key_size);
|
||||
@@ -438,7 +439,7 @@ int LUKS2_config_set_flags(struct crypt_device *cd, struct luks2_hdr *hdr, uint3
|
||||
/*
|
||||
* Requirements for device activation or header modification
|
||||
*/
|
||||
int LUKS2_config_get_requirements(struct crypt_device *cd, struct luks2_hdr *hdr, uint32_t *reqs);
|
||||
void LUKS2_config_get_requirements(struct crypt_device *cd, struct luks2_hdr *hdr, uint32_t *reqs);
|
||||
int LUKS2_config_set_requirements(struct crypt_device *cd, struct luks2_hdr *hdr, uint32_t reqs, bool commit);
|
||||
int LUKS2_config_set_requirement_version(struct crypt_device *cd, struct luks2_hdr *hdr, uint32_t req_id, uint8_t req_version, bool commit);
|
||||
|
||||
@@ -446,12 +447,10 @@ int LUKS2_config_get_reencrypt_version(struct luks2_hdr *hdr, uint8_t *version);
|
||||
|
||||
bool LUKS2_reencrypt_requirement_candidate(struct luks2_hdr *hdr);
|
||||
|
||||
int LUKS2_unmet_requirements(struct crypt_device *cd, struct luks2_hdr *hdr, uint32_t reqs_mask, int quiet);
|
||||
int LUKS2_unmet_requirements(struct crypt_device *cd, struct luks2_hdr *hdr, uint64_t reqs_mask, int quiet);
|
||||
|
||||
int LUKS2_key_description_by_segment(struct crypt_device *cd,
|
||||
struct luks2_hdr *hdr, struct volume_key *vk, int segment);
|
||||
int LUKS2_volume_key_load_in_keyring_by_keyslot(struct crypt_device *cd,
|
||||
struct luks2_hdr *hdr, struct volume_key *vk, int keyslot);
|
||||
int LUKS2_volume_key_load_in_keyring_by_digest(struct crypt_device *cd,
|
||||
struct volume_key *vk, int digest);
|
||||
|
||||
@@ -465,12 +464,8 @@ int LUKS2_luks2_to_luks1(struct crypt_device *cd,
|
||||
/*
|
||||
* LUKS2 reencryption
|
||||
*/
|
||||
int LUKS2_reencrypt_locked_recovery_by_passphrase(struct crypt_device *cd,
|
||||
int keyslot_old,
|
||||
int keyslot_new,
|
||||
const char *passphrase,
|
||||
size_t passphrase_size,
|
||||
struct volume_key **vks);
|
||||
int LUKS2_reencrypt_locked_recovery_by_vks(struct crypt_device *cd,
|
||||
struct volume_key *vks);
|
||||
|
||||
void LUKS2_reencrypt_free(struct crypt_device *cd,
|
||||
struct luks2_reencrypt *rh);
|
||||
@@ -494,19 +489,13 @@ int LUKS2_reencrypt_check_device_size(struct crypt_device *cd,
|
||||
struct luks2_hdr *hdr,
|
||||
uint64_t check_size,
|
||||
uint64_t *dev_size,
|
||||
bool activation,
|
||||
bool device_exclusive_check,
|
||||
bool dynamic);
|
||||
|
||||
int LUKS2_reencrypt_digest_verify(struct crypt_device *cd,
|
||||
struct luks2_hdr *hdr,
|
||||
struct volume_key *vks);
|
||||
|
||||
int LUKS2_reencrypt_max_hotzone_size(struct crypt_device *cd,
|
||||
struct luks2_hdr *hdr,
|
||||
const struct reenc_protection *rp,
|
||||
int reencrypt_keyslot,
|
||||
uint64_t *r_length);
|
||||
|
||||
void LUKS2_reencrypt_protection_erase(struct reenc_protection *rp);
|
||||
unsigned LUKS2_reencrypt_vks_count(struct luks2_hdr *hdr);
|
||||
|
||||
#endif
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user