mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-10 10:20:01 +01:00
Compare commits
615 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e0562f9708 | ||
|
|
6462ee55d3 | ||
|
|
91ba5742c6 | ||
|
|
667e469659 | ||
|
|
37cecb5a5b | ||
|
|
a47ebccf9a | ||
|
|
584d5b8d65 | ||
|
|
8eef5bde4f | ||
|
|
3532be48c7 | ||
|
|
5f7309bfa0 | ||
|
|
fa4a246744 | ||
|
|
321386db88 | ||
|
|
b99b4825a2 | ||
|
|
9b455125e9 | ||
|
|
adcb9bfb7d | ||
|
|
4abfd38169 | ||
|
|
b684fffdaf | ||
|
|
fb3b62ca02 | ||
|
|
c469e458b7 | ||
|
|
be5473f242 | ||
|
|
527c0fe4f9 | ||
|
|
0ec4d4c9cf | ||
|
|
28f860def2 | ||
|
|
42abcc0fac | ||
|
|
a38fcafcff | ||
|
|
c4a533c3d5 | ||
|
|
96f31a2cff | ||
|
|
8f4fb9303f | ||
|
|
336be2da96 | ||
|
|
e129bffce9 | ||
|
|
a9d9a2ad44 | ||
|
|
c0a5293435 | ||
|
|
b9ae00956d | ||
|
|
e37016bf64 | ||
|
|
104c7d6c4f | ||
|
|
b773823a1b | ||
|
|
0894814148 | ||
|
|
cc948df1dd | ||
|
|
35e3660c61 | ||
|
|
28c6901de1 | ||
|
|
dc067454c1 | ||
|
|
32c2bd4222 | ||
|
|
cd4ea1c348 | ||
|
|
8984e47414 | ||
|
|
491e79db4c | ||
|
|
8a1a0547a8 | ||
|
|
9d47892342 | ||
|
|
32cfb1ca25 | ||
|
|
810aef34ca | ||
|
|
b23b3c4dfe | ||
|
|
b9d99a1626 | ||
|
|
496a07ed4c | ||
|
|
fbba97552e | ||
|
|
0cefe2d107 | ||
|
|
768426ad99 | ||
|
|
5a48ff5eb2 | ||
|
|
96c8c7ba56 | ||
|
|
29c2281ab2 | ||
|
|
0d70651c5a | ||
|
|
b1fb2532e0 | ||
|
|
05b695d516 | ||
|
|
44c9b2fc68 | ||
|
|
018205a9a0 | ||
|
|
c333108c61 | ||
|
|
2fcb521c77 | ||
|
|
0dc87d45a8 | ||
|
|
03dc073f2b | ||
|
|
b402f087d7 | ||
|
|
656fbde7d1 | ||
|
|
a89e6c0ca6 | ||
|
|
d380da7a32 | ||
|
|
0de4b65ba6 | ||
|
|
5c7954a0c7 | ||
|
|
62f334cfa5 | ||
|
|
6d2c15ea79 | ||
|
|
4b8f91d0d9 | ||
|
|
c364290be9 | ||
|
|
a14aab5df7 | ||
|
|
47c5b5ed06 | ||
|
|
0eae181092 | ||
|
|
1cbc53e8ee | ||
|
|
7535fdb31b | ||
|
|
de9393879e | ||
|
|
db51a343de | ||
|
|
e2375c8368 | ||
|
|
697c6c9324 | ||
|
|
6d07be898d | ||
|
|
ade21e6c60 | ||
|
|
fcf5b414d6 | ||
|
|
92d1bebdac | ||
|
|
39a5408e98 | ||
|
|
937f969cc4 | ||
|
|
f4101d0f8b | ||
|
|
ce2218ed65 | ||
|
|
cdae1b4c60 | ||
|
|
c4b16923bb | ||
|
|
b016e65daa | ||
|
|
c35839afbc | ||
|
|
cd8826618d | ||
|
|
ab0f7346bc | ||
|
|
9fb8b816c5 | ||
|
|
0e79728f86 | ||
|
|
4b0b82adc5 | ||
|
|
850799802b | ||
|
|
ed1b59fd25 | ||
|
|
fa98297547 | ||
|
|
2949f37587 | ||
|
|
fca7296e6e | ||
|
|
6aa77550c5 | ||
|
|
23e1ac341c | ||
|
|
9ae7e122ac | ||
|
|
73493c1f44 | ||
|
|
65c4c62f78 | ||
|
|
aba52fa878 | ||
|
|
a5cc87b4a5 | ||
|
|
11ee2876a6 | ||
|
|
20eea64334 | ||
|
|
44165a1bbb | ||
|
|
e9bc8e1b35 | ||
|
|
5e52599326 | ||
|
|
4903b8120b | ||
|
|
d0c98af4e6 | ||
|
|
624157ef7b | ||
|
|
08da00c94a | ||
|
|
9910c7dcd0 | ||
|
|
9ff422374d | ||
|
|
5c49268c47 | ||
|
|
7df1d83ebb | ||
|
|
555d5f6e97 | ||
|
|
716e60729d | ||
|
|
65ba7c7f3f | ||
|
|
ed1ab3e498 | ||
|
|
dc371d7174 | ||
|
|
cf1e6fb847 | ||
|
|
45e0942755 | ||
|
|
0f4431d0bb | ||
|
|
54b21c6e46 | ||
|
|
c2a33b480f | ||
|
|
490c17b3cd | ||
|
|
f8aa0bc084 | ||
|
|
ba7d9967a8 | ||
|
|
adaf6d3eb4 | ||
|
|
bbc3339bda | ||
|
|
f720affe8c | ||
|
|
a718369374 | ||
|
|
4b6ec2a8c2 | ||
|
|
e48a808b5c | ||
|
|
f929abacab | ||
|
|
1562879369 | ||
|
|
e1d410953b | ||
|
|
8818eb2687 | ||
|
|
4320327383 | ||
|
|
5c4c3010fc | ||
|
|
c16ebd0aca | ||
|
|
d392737279 | ||
|
|
be204f8978 | ||
|
|
9391477be4 | ||
|
|
09fd551e03 | ||
|
|
ee8425b836 | ||
|
|
2499fa669d | ||
|
|
bd047d03ef | ||
|
|
9511c91a79 | ||
|
|
570b0ecd49 | ||
|
|
80290266e6 | ||
|
|
dc7f97ea5e | ||
|
|
c9279c9818 | ||
|
|
9341679b31 | ||
|
|
78cac9a97c | ||
|
|
075fb8d261 | ||
|
|
9bce441a1e | ||
|
|
5b41568e8f | ||
|
|
0becb1ac46 | ||
|
|
fff8b02b46 | ||
|
|
83564fbeb9 | ||
|
|
b30b53e4a7 | ||
|
|
60d60d971a | ||
|
|
5596294635 | ||
|
|
54bf872663 | ||
|
|
4b109507d8 | ||
|
|
625822e5a1 | ||
|
|
18c4896310 | ||
|
|
d542045645 | ||
|
|
2199076fef | ||
|
|
37902e1287 | ||
|
|
30f7e2310f | ||
|
|
89d9d25a2b | ||
|
|
0d766c5868 | ||
|
|
313e5564fe | ||
|
|
0e52cb902a | ||
|
|
3684a5d833 | ||
|
|
a5aa30be33 | ||
|
|
eb2b03699f | ||
|
|
3da3b415a7 | ||
|
|
03cc3383e1 | ||
|
|
4988c8beea | ||
|
|
3a0ac6c3d3 | ||
|
|
203f2e082d | ||
|
|
b4e2306da8 | ||
|
|
c0d55945d3 | ||
|
|
3a3ff16c39 | ||
|
|
774d1de56e | ||
|
|
01938e3cdd | ||
|
|
24213963fd | ||
|
|
6d8aeb1d58 | ||
|
|
6fe40949f9 | ||
|
|
c1b01c2dc7 | ||
|
|
a24d9cd9b5 | ||
|
|
1b982af46f | ||
|
|
66f042953d | ||
|
|
4f2d4f98e3 | ||
|
|
251c7f434f | ||
|
|
7835b365a7 | ||
|
|
4aee070173 | ||
|
|
ef078587cc | ||
|
|
6e119ab6cc | ||
|
|
c490ef638b | ||
|
|
f5d777e412 | ||
|
|
28eddd2f52 | ||
|
|
eb4720819e | ||
|
|
088a927c07 | ||
|
|
3c3e9570c4 | ||
|
|
b6e046835e | ||
|
|
158a5de3b4 | ||
|
|
02e36d7606 | ||
|
|
38ff882096 | ||
|
|
58a27a18ca | ||
|
|
94fb0b7781 | ||
|
|
c401fe3d04 | ||
|
|
3b10bf9558 | ||
|
|
d6016b1c2d | ||
|
|
9908cd4746 | ||
|
|
a24a594d1a | ||
|
|
56e73526ad | ||
|
|
e640f5e006 | ||
|
|
cb7fa0b9c7 | ||
|
|
60d59b0bc0 | ||
|
|
4f33a537ae | ||
|
|
96bddb363f | ||
|
|
dac000e1df | ||
|
|
be246c16ab | ||
|
|
cc3b39980b | ||
|
|
8c54d938ac | ||
|
|
d7960b9307 | ||
|
|
4e9fa4d2bb | ||
|
|
7a773f70f3 | ||
|
|
b72473eddf | ||
|
|
4d1b67eeb2 | ||
|
|
f54c7939f0 | ||
|
|
19bde65f5b | ||
|
|
d2fbc963ca | ||
|
|
61bec51be0 | ||
|
|
84ada5ddf6 | ||
|
|
7158c32b96 | ||
|
|
1a8bae8884 | ||
|
|
538169fb5b | ||
|
|
963ee0e6ee | ||
|
|
d20e2ff02d | ||
|
|
d5e48fcb00 | ||
|
|
4d99773009 | ||
|
|
f3ed801e8b | ||
|
|
1954792876 | ||
|
|
95009fff4b | ||
|
|
b8a7125225 | ||
|
|
6cede067a2 | ||
|
|
906c7897e1 | ||
|
|
c5b64b5479 | ||
|
|
4a295781d1 | ||
|
|
1f9efdf59a | ||
|
|
1f776bc979 | ||
|
|
104130c4c4 | ||
|
|
51d74c6029 | ||
|
|
7fe10e3d7b | ||
|
|
25c3271cd0 | ||
|
|
7665f8e805 | ||
|
|
6361e86daf | ||
|
|
3c5481709b | ||
|
|
c30fe505c5 | ||
|
|
a9ce2210bc | ||
|
|
e5244bc47c | ||
|
|
23e144daf4 | ||
|
|
03a8ba4d17 | ||
|
|
f80b506b65 | ||
|
|
f7f9e291f4 | ||
|
|
1bf26b9a90 | ||
|
|
261d0d05a5 | ||
|
|
9c71c74d59 | ||
|
|
39e6cfcb8a | ||
|
|
913ef7c07e | ||
|
|
69bd90055f | ||
|
|
7d496a6b69 | ||
|
|
642a838343 | ||
|
|
a1306ed01c | ||
|
|
790ef04304 | ||
|
|
d44d07c9eb | ||
|
|
5b8fb6f135 | ||
|
|
84079a1a49 | ||
|
|
1b7c97c333 | ||
|
|
96d67485d9 | ||
|
|
a5757c35f0 | ||
|
|
3f49ffd526 | ||
|
|
dfd018235b | ||
|
|
1114135a83 | ||
|
|
d5089c5fde | ||
|
|
a3a549320f | ||
|
|
8866e88ec5 | ||
|
|
42be679df3 | ||
|
|
b2569b6d5c | ||
|
|
4f657c17a2 | ||
|
|
2755f37266 | ||
|
|
4c08eedaca | ||
|
|
62309b345a | ||
|
|
9e9bf5ca56 | ||
|
|
b53b577b19 | ||
|
|
4f9e3e6a44 | ||
|
|
db012091a8 | ||
|
|
a1ad5894ca | ||
|
|
afd526a8c4 | ||
|
|
35d6914779 | ||
|
|
9ca1ac5a39 | ||
|
|
da784ff5bc | ||
|
|
1b58fab430 | ||
|
|
91372cb69c | ||
|
|
231a2e932d | ||
|
|
5d2205a2f8 | ||
|
|
b9b04c3d1e | ||
|
|
0626fae601 | ||
|
|
2a8a235df9 | ||
|
|
e95ed30c66 | ||
|
|
47c76c34fb | ||
|
|
606b2a9286 | ||
|
|
38590eaef2 | ||
|
|
6371786093 | ||
|
|
bdc3fdcd0d | ||
|
|
22e5cda9c6 | ||
|
|
8256b673a1 | ||
|
|
2072adf705 | ||
|
|
49ea1b69fe | ||
|
|
9dd87865bc | ||
|
|
c31854e2b3 | ||
|
|
bce295738b | ||
|
|
4382e21610 | ||
|
|
93da52f883 | ||
|
|
aef20fe02e | ||
|
|
181aeeed3a | ||
|
|
bf73c4357e | ||
|
|
04da641b44 | ||
|
|
03892be6ed | ||
|
|
e937feb1a7 | ||
|
|
143603c471 | ||
|
|
85e71a8680 | ||
|
|
ddcdd76cc2 | ||
|
|
4505d0a36b | ||
|
|
d658159ae5 | ||
|
|
9ba3bb3a5e | ||
|
|
e905a36561 | ||
|
|
762e9afd78 | ||
|
|
abe10085b1 | ||
|
|
9d799327b4 | ||
|
|
d66aac1683 | ||
|
|
6e262e0de1 | ||
|
|
25512d89ae | ||
|
|
e1cc40df7e | ||
|
|
b7498adc1c | ||
|
|
01e03f7002 | ||
|
|
dd9bff8d67 | ||
|
|
5ca29818e9 | ||
|
|
13f4feaaf7 | ||
|
|
be3448fb8a | ||
|
|
d9ba34693f | ||
|
|
b5a5564ac1 | ||
|
|
005855ce90 | ||
|
|
6083652089 | ||
|
|
2124cbf5ee | ||
|
|
eb29f40384 | ||
|
|
4f3a65a629 | ||
|
|
0e8d61035b | ||
|
|
0165301357 | ||
|
|
0b5418c02f | ||
|
|
3e6935b7ab | ||
|
|
cf902b0e2d | ||
|
|
049c2a5cbe | ||
|
|
2983c7d96d | ||
|
|
65051b4942 | ||
|
|
e0dab9e99f | ||
|
|
0a905364fa | ||
|
|
f0bb160f71 | ||
|
|
044cb58588 | ||
|
|
49937ac591 | ||
|
|
66bea4b3be | ||
|
|
af87ffbd37 | ||
|
|
f48c312fc7 | ||
|
|
9da29e8759 | ||
|
|
6b42f15a95 | ||
|
|
8d48bf79ea | ||
|
|
5d9953ea51 | ||
|
|
e2fbcea56a | ||
|
|
d04d9f336a | ||
|
|
7b6eda0d27 | ||
|
|
0ccb4a2d3b | ||
|
|
ca73541753 | ||
|
|
e8e805dfd3 | ||
|
|
058976ff08 | ||
|
|
4b0e7ae41d | ||
|
|
68c2ac1087 | ||
|
|
6cae0b0efb | ||
|
|
80c101d15c | ||
|
|
476c4553a5 | ||
|
|
0e39341be7 | ||
|
|
fec17febe6 | ||
|
|
38c694a143 | ||
|
|
685f1300cb | ||
|
|
ff0e81f656 | ||
|
|
c01c4338b1 | ||
|
|
78a160b3c0 | ||
|
|
c066fddf8b | ||
|
|
230ac16201 | ||
|
|
b13b4b7654 | ||
|
|
f4eef16539 | ||
|
|
bbb3818ec7 | ||
|
|
a70b27762d | ||
|
|
655007995b | ||
|
|
8e1c407ed6 | ||
|
|
37ae78c9d8 | ||
|
|
d876ce975c | ||
|
|
014206399a | ||
|
|
312d8eca73 | ||
|
|
b861d1e7f4 | ||
|
|
f90edb6133 | ||
|
|
6258753b1a | ||
|
|
b7caa72acd | ||
|
|
c9881f8c33 | ||
|
|
7b42e0b99c | ||
|
|
988b1f95fd | ||
|
|
791481b9e9 | ||
|
|
2fbf5994f4 | ||
|
|
a38cb2375f | ||
|
|
dfe77be748 | ||
|
|
c3f3865485 | ||
|
|
3ae161df5d | ||
|
|
3a5a1ea0e7 | ||
|
|
6fde2f640b | ||
|
|
ec3b767103 | ||
|
|
bb8e085378 | ||
|
|
3b50005d2f | ||
|
|
ef10cd09ec | ||
|
|
88db040e34 | ||
|
|
6dac2726f5 | ||
|
|
73f8eeb0ef | ||
|
|
9679fb7f25 | ||
|
|
8c444b563e | ||
|
|
7f5f12e892 | ||
|
|
1c3245ca82 | ||
|
|
16ad14d2c6 | ||
|
|
b117dcc209 | ||
|
|
63aabc6b3c | ||
|
|
d5a13e8aad | ||
|
|
ef44e6e3d3 | ||
|
|
cf4fec3865 | ||
|
|
dd166339c5 | ||
|
|
4a6edf0c2e | ||
|
|
dde782ac22 | ||
|
|
cd05880a5a | ||
|
|
ac9cf0cd10 | ||
|
|
3935f79ea6 | ||
|
|
39b48a4d1d | ||
|
|
a707ec6200 | ||
|
|
64072e0e20 | ||
|
|
1e03a34ccb | ||
|
|
0a68f45bb2 | ||
|
|
be60731d0f | ||
|
|
7e715a94bb | ||
|
|
0d68754de5 | ||
|
|
6ec29d935f | ||
|
|
49463051bc | ||
|
|
cf95e23dd5 | ||
|
|
b4ebe0be18 | ||
|
|
231ab0167b | ||
|
|
205d62af89 | ||
|
|
4635d7bf31 | ||
|
|
6b81dd6a6f | ||
|
|
cddf4d859d | ||
|
|
5ec2bba807 | ||
|
|
b237358079 | ||
|
|
355bd4a224 | ||
|
|
cd57ff672c | ||
|
|
cdd6f94c56 | ||
|
|
4ac7e5a4d2 | ||
|
|
fd833b625d | ||
|
|
e38a19f5e9 | ||
|
|
f47b7ba425 | ||
|
|
5107296213 | ||
|
|
19dc09131d | ||
|
|
78d014e27d | ||
|
|
c10aff8a9d | ||
|
|
611278ca39 | ||
|
|
a35c0694b1 | ||
|
|
1dcd5a3de5 | ||
|
|
346e1d1264 | ||
|
|
39d5fd28ed | ||
|
|
0516a1a676 | ||
|
|
17c87c1148 | ||
|
|
566f48f7a4 | ||
|
|
4f14b43a3d | ||
|
|
4a42f27d78 | ||
|
|
d39b33a371 | ||
|
|
71c0c1f26d | ||
|
|
743fbbc451 | ||
|
|
7d207b7725 | ||
|
|
0007cd537d | ||
|
|
a058606210 | ||
|
|
f46683d0c2 | ||
|
|
37708b7cad | ||
|
|
ba7e7f94bf | ||
|
|
448c401fbc | ||
|
|
1a947a573b | ||
|
|
6c3a4cf331 | ||
|
|
37d693cfc2 | ||
|
|
925dac2c50 | ||
|
|
d93a925b5c | ||
|
|
9eac56c614 | ||
|
|
4af7114832 | ||
|
|
ed1586950a | ||
|
|
311727a571 | ||
|
|
a97b56cc32 | ||
|
|
0575ded2aa | ||
|
|
f61fbc7520 | ||
|
|
1f87cbc5bf | ||
|
|
107ce07914 | ||
|
|
550c38dd78 | ||
|
|
909c77e856 | ||
|
|
ad224b479a | ||
|
|
163abe3520 | ||
|
|
1c91890aac | ||
|
|
8802e42ab3 | ||
|
|
42f8e5bdce | ||
|
|
dc4d945e88 | ||
|
|
403559261a | ||
|
|
b408947a36 | ||
|
|
4d6dd0df96 | ||
|
|
c6aa3c5d21 | ||
|
|
ad34580916 | ||
|
|
1c58538b6d | ||
|
|
74e68760b7 | ||
|
|
7dcd983360 | ||
|
|
df389199d0 | ||
|
|
6c900eea72 | ||
|
|
1b85f4c38b | ||
|
|
458cadf4ee | ||
|
|
c3064c9442 | ||
|
|
16faeae057 | ||
|
|
e618f38929 | ||
|
|
ecf73237e2 | ||
|
|
4a5bfd7509 | ||
|
|
e698843420 | ||
|
|
70606301ef | ||
|
|
873017d0fa | ||
|
|
6a14ba8eb5 | ||
|
|
2bda053677 | ||
|
|
56eb6b0253 | ||
|
|
047ed83303 | ||
|
|
2620be03f0 | ||
|
|
8dcdf1349e | ||
|
|
194842375d | ||
|
|
3e037b7422 | ||
|
|
de95a38381 | ||
|
|
8bec41ab34 | ||
|
|
5ca9cfde59 | ||
|
|
64c1168b9a | ||
|
|
3a3d3e89e5 | ||
|
|
93796f4036 | ||
|
|
c096166e48 | ||
|
|
fddd7125ca | ||
|
|
e026f089be | ||
|
|
f51c7b62db | ||
|
|
ecf46df00e | ||
|
|
935e83ebfa | ||
|
|
1e7d8afc99 | ||
|
|
1cc33f943e | ||
|
|
e479b0988f | ||
|
|
76d7fab0c7 | ||
|
|
dfadce6d80 | ||
|
|
a47856ac49 | ||
|
|
3cea5dcc7b | ||
|
|
52b0271a0e | ||
|
|
bcd94f6ad4 | ||
|
|
771db939ad | ||
|
|
8a0553d452 | ||
|
|
c878e56237 | ||
|
|
3deabc8e56 | ||
|
|
7bc5829c43 | ||
|
|
d70782478e | ||
|
|
344a162a29 | ||
|
|
74b26c7b8a | ||
|
|
cee0f0b49f | ||
|
|
bf7819ccef | ||
|
|
4e471a9b03 | ||
|
|
ab953b3ff6 | ||
|
|
5c42db87bf | ||
|
|
04a0f5dfb8 | ||
|
|
b30c1c7f43 | ||
|
|
d980dbb300 | ||
|
|
02707608db | ||
|
|
a0d1056e0f | ||
|
|
a0b795becb | ||
|
|
1a10c59b97 | ||
|
|
88bdb609a8 | ||
|
|
ed9e146cb6 | ||
|
|
7e7c9c176c | ||
|
|
aab7fecd2e | ||
|
|
c5c403323e | ||
|
|
4a257d8c65 | ||
|
|
f60475e293 | ||
|
|
e3e3027e12 | ||
|
|
a3c8571df0 | ||
|
|
ea0ee83025 |
1
AUTHORS
1
AUTHORS
@@ -1,2 +1,3 @@
|
||||
Christophe Saout <christophe@saout.de>
|
||||
Clemens Fruhwirth <clemens@endorphin.org>
|
||||
Milan Broz <asi@ucw.cz>
|
||||
|
||||
56
COPYING
56
COPYING
@@ -1,12 +1,12 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
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
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
@@ -15,7 +15,7 @@ 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 Library General Public License instead.) You can apply it to
|
||||
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
|
||||
@@ -55,8 +55,8 @@ 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
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
@@ -110,7 +110,7 @@ above, provided that you also meet all of these conditions:
|
||||
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
|
||||
@@ -168,7 +168,7 @@ 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
|
||||
@@ -225,7 +225,7 @@ 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
|
||||
@@ -255,7 +255,7 @@ 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
|
||||
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
|
||||
@@ -277,9 +277,9 @@ 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
|
||||
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
|
||||
@@ -303,17 +303,16 @@ the "copyright" line and a pointer to where the full notice is found.
|
||||
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
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 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.
|
||||
@@ -336,5 +335,20 @@ necessary. Here is a sample; alter the names:
|
||||
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 Library General
|
||||
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.
|
||||
|
||||
502
COPYING.LGPL
Normal file
502
COPYING.LGPL
Normal file
@@ -0,0 +1,502 @@
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 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.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
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 and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it becomes
|
||||
a de-facto standard. To achieve this, non-free programs must be
|
||||
allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, 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 library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete 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 distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
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 Library or any portion
|
||||
of it, thus forming a work based on the Library, 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) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
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 Library, 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 Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you 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.
|
||||
|
||||
If distribution of 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 satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be 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.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library 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.
|
||||
|
||||
9. 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 Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
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 with
|
||||
this License.
|
||||
|
||||
11. 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 Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library 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 Library.
|
||||
|
||||
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.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library 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.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Lesser 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 Library
|
||||
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 Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
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
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "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
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. 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 LIBRARY 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
|
||||
LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), 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 Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms of the
|
||||
ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library. 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 library's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This library 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 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser 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
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
||||
425
ChangeLog
425
ChangeLog
@@ -1,3 +1,420 @@
|
||||
2012-07-10 Milan Broz <gmazyland@gmail.com>
|
||||
* Version 1.5.0.
|
||||
|
||||
2012-06-25 Milan Broz <gmazyland@gmail.com>
|
||||
* Add --device-size option for reencryption tool.
|
||||
* Switch to use unit suffix for --reduce-device-size option.
|
||||
* Remove open device debugging feature (no longer needed).
|
||||
* Fix library name for FIPS check.
|
||||
|
||||
2012-06-20 Milan Broz <gmazyland@gmail.com>
|
||||
* Version 1.5.0-rc2.
|
||||
|
||||
2012-06-18 Milan Broz <gmazyland@gmail.com>
|
||||
* Introduce cryptsetup-reencrypt - experimental offline LUKS reencryption tool.
|
||||
* Fix luks-header-from-active script (do not use LUKS header on-disk, add UUID).
|
||||
* Add --test-passphrase option for luksOpen (check passphrase only).
|
||||
|
||||
2012-06-11 Milan Broz <gmazyland@gmail.com>
|
||||
* Introduce veritysetup for dm-verity target management.
|
||||
* Version 1.5.0-rc1.
|
||||
|
||||
2012-06-10 Milan Broz <gmazyland@gmail.com>
|
||||
* Both data and header device can now be a file.
|
||||
* Loop is automatically allocated in crypt_set_data_device().
|
||||
* Require only up to last keyslot area for header device (ignore data offset).
|
||||
* Fix header backup and restore to work on files with large data offset.
|
||||
|
||||
2012-05-27 Milan Broz <gmazyland@gmail.com>
|
||||
* Fix readonly activation if underlying device is readonly (1.4.0).
|
||||
* Include stddef.h in libdevmapper.h (size_t definition).
|
||||
* Version 1.4.3.
|
||||
|
||||
2012-05-21 Milan Broz <gmazyland@gmail.com>
|
||||
* Add --enable-fips for linking with fipscheck library.
|
||||
* Initialize binary and library selfcheck if running in FIPS mode.
|
||||
* Use FIPS RNG in FIPS mode for KEY and SALT (only gcrypt backend supported).
|
||||
|
||||
2012-05-09 Milan Broz <gmazyland@gmail.com>
|
||||
* Fix keyslot removal (wipe keyslot) for device with 4k hw block (1.4.0).
|
||||
* Allow empty cipher (cipher_null) for testing.
|
||||
|
||||
2012-05-02 Milan Broz <gmazyland@gmail.com>
|
||||
* Fix loop mapping on readonly file.
|
||||
* Relax --shared test, allow mapping even for overlapping segments.
|
||||
* Support shared flag for LUKS devices (dangerous).
|
||||
* Switch on retry on device remove for libdevmapper.
|
||||
* Allow "private" activation (skip some udev global rules) flag.
|
||||
|
||||
2012-04-09 Milan Broz <gmazyland@gmail.com>
|
||||
* Fix header check to support old (cryptsetup 1.0.0) header alignment. (1.4.0)
|
||||
* Version 1.4.2.
|
||||
|
||||
2012-03-16 Milan Broz <gmazyland@gmail.com>
|
||||
* Add --keyfile-offset and --new-keyfile-offset parameters to API and CLI.
|
||||
* Add repair command and crypt_repair() for known LUKS metadata problems repair.
|
||||
* Allow to specify --align-payload only for luksFormat.
|
||||
|
||||
2012-03-16 Milan Broz <mbroz@redhat.com>
|
||||
* Unify password verification option.
|
||||
* Support password verification with quiet flag if possible. (1.2.0)
|
||||
* Fix retry if entered passphrases (with verify option) do not match.
|
||||
* Support UUID=<LUKS_UUID> format for device specification.
|
||||
|
||||
2012-02-11 Milan Broz <mbroz@redhat.com>
|
||||
* Add --master-key-file option to luksOpen (open using volume key).
|
||||
|
||||
2012-01-12 Milan Broz <mbroz@redhat.com>
|
||||
* Fix use of empty keyfile.
|
||||
|
||||
2011-11-13 Milan Broz <mbroz@redhat.com>
|
||||
* Fix error message for luksClose and detached LUKS header.
|
||||
* Allow --header for status command to get full info with detached header.
|
||||
|
||||
2011-11-09 Milan Broz <mbroz@redhat.com>
|
||||
* Version 1.4.1.
|
||||
|
||||
2011-11-05 Milan Broz <mbroz@redhat.com>
|
||||
* Merge pycryptsetup (Python libcryptsetup bindings).
|
||||
* Fix stupid typo in set_iteration_time API call.
|
||||
* Fix cryptsetup status output if parameter is device path.
|
||||
|
||||
2011-10-27 Milan Broz <mbroz@redhat.com>
|
||||
* Fix crypt_get_volume_key_size() for plain device.
|
||||
* Fix FSF address in license text.
|
||||
|
||||
2011-10-25 Milan Broz <mbroz@redhat.com>
|
||||
* Print informative message in isLuks only in verbose mode.
|
||||
* Version 1.4.0.
|
||||
|
||||
2011-10-10 Milan Broz <mbroz@redhat.com>
|
||||
* Version 1.4.0-rc1.
|
||||
|
||||
2011-10-05 Milan Broz <mbroz@redhat.com>
|
||||
* Support Nettle 2.4 crypto backend (for ripemd160).
|
||||
* If device is not rotational, do not use Gutmann wipe method.
|
||||
* Add crypt_last_error() API call.
|
||||
* Fix luksKillSLot exit code if slot is inactive or invalid.
|
||||
* Fix exit code if passphrases do not match in luksAddKey.
|
||||
* Add LUKS on-disk format description into package.
|
||||
|
||||
2011-09-22 Milan Broz <mbroz@redhat.com>
|
||||
* Support key-slot option for luksOpen (use only explicit keyslot).
|
||||
|
||||
2011-08-22 Milan Broz <mbroz@redhat.com>
|
||||
* Add more paranoid checks for LUKS header and keyslot attributes.
|
||||
* Fix crypt_load to properly check device size.
|
||||
* Use new /dev/loop-control (kernel 3.1) if possible.
|
||||
* Enhance check of device size before writing LUKS header.
|
||||
* Do not allow context format of already formatted device.
|
||||
|
||||
2011-07-25 Milan Broz <mbroz@redhat.com>
|
||||
* Remove hash/hmac restart from crypto backend and make it part of hash/hmac final.
|
||||
* Improve check for invalid offset and size values.
|
||||
|
||||
2011-07-19 Milan Broz <mbroz@redhat.com>
|
||||
* Revert default initialisation of volume key in crypt_init_by_name().
|
||||
* Do not allow key retrieval while suspended (key could be wiped).
|
||||
* Do not allow suspend for non-LUKS devices.
|
||||
* Support retries and timeout parameters for luksSuspend.
|
||||
* Add --header option for detached metadata (on-disk LUKS header) device.
|
||||
* Add crypt_init_by_name_and_header() and crypt_set_data_device() to API.
|
||||
* Allow different data offset setting for detached header.
|
||||
|
||||
2011-07-07 Milan Broz <mbroz@redhat.com>
|
||||
* Remove old API functions (all functions using crypt_options).
|
||||
* Add --enable-discards option to allow discards/TRIM requests.
|
||||
* Add crypt_get_iv_offset() function to API.
|
||||
|
||||
2011-07-01 Milan Broz <mbroz@redhat.com>
|
||||
* Add --shared option for creating non-overlapping crypt segments.
|
||||
* Add shared flag to libcryptsetup api.
|
||||
* Fix plain crypt format parameters to include size option (API change).
|
||||
|
||||
2011-06-08 Milan Broz <mbroz@redhat.com>
|
||||
* Fix return code for status command when device doesn't exists.
|
||||
|
||||
2011-05-24 Milan Broz <mbroz@redhat.com>
|
||||
* Version 1.3.1.
|
||||
|
||||
2011-05-17 Milan Broz <mbroz@redhat.com>
|
||||
* Fix keyfile=- processing in create command (1.3.0).
|
||||
* Simplify device path status check.
|
||||
|
||||
2011-05-03 Milan Broz <mbroz@redhat.com>
|
||||
* Do not ignore size argument for create command (1.2.0).
|
||||
|
||||
2011-04-18 Milan Broz <mbroz@redhat.com>
|
||||
* Fix error paths in blockwise code and lseek_write call.
|
||||
* Add Nettle crypto backend support.
|
||||
|
||||
2011-04-05 Milan Broz <mbroz@redhat.com>
|
||||
* Version 1.3.0.
|
||||
|
||||
2011-03-22 Milan Broz <mbroz@redhat.com>
|
||||
* Also support --skip and --hash option for loopaesOpen.
|
||||
* Fix return code when passphrase is read from pipe.
|
||||
* Document cryptsetup exit codes.
|
||||
|
||||
2011-03-18 Milan Broz <mbroz@redhat.com>
|
||||
* Respect maximum keyfile size paramater.
|
||||
* Introduce maximum default keyfile size, add configure option.
|
||||
* Require the whole key read from keyfile in create command (broken in 1.2.0).
|
||||
* Fix offset option for loopaesOpen.
|
||||
* Lock memory also in luksDump command.
|
||||
* Version 1.3.0-rc2.
|
||||
|
||||
2011-03-14 Milan Broz <mbroz@redhat.com>
|
||||
* Version 1.3.0-rc1.
|
||||
|
||||
2011-03-11 Milan Broz <mbroz@redhat.com>
|
||||
* Add loop manipulation code and support mapping of images in file.
|
||||
* Add backing device loop info into status message.
|
||||
* Add luksChangeKey command.
|
||||
|
||||
2011-03-05 Milan Broz <mbroz@redhat.com>
|
||||
* Add exception to COPYING for binary distribution linked with OpenSSL library.
|
||||
* Set secure data flag (wipe all ioclt buffers) if devmapper library supports it.
|
||||
|
||||
2011-01-29 Milan Broz <mbroz@redhat.com>
|
||||
* Fix mapping removal if device disappeared but node still exists.
|
||||
* Fix luksAddKey return code if master key is used.
|
||||
|
||||
2011-01-25 Milan Broz <mbroz@redhat.com>
|
||||
* Add loop-AES handling (loopaesOpen and loopaesClose commands).
|
||||
(requires kernel 2.6.38 and above)
|
||||
|
||||
2011-01-05 Milan Broz <mbroz@redhat.com>
|
||||
* Fix static build (--disable-static-cryptsetup now works properly).
|
||||
|
||||
2010-12-30 Milan Broz <mbroz@redhat.com>
|
||||
* Add compile time crypto backends implementation
|
||||
(gcrypt, OpenSSL, NSS and userspace Linux kernel crypto api).
|
||||
* Currently NSS is lacking ripemd160, cannot provide full plain compatibility.
|
||||
* Use --with-crypto_backend=[gcrypt|openssl|nss|kernel] to configure.
|
||||
|
||||
2010-12-20 Milan Broz <mbroz@redhat.com>
|
||||
* Version 1.2.0.
|
||||
|
||||
2010-11-25 Milan Broz <mbroz@redhat.com>
|
||||
* Fix crypt_activate_by_keyfile() to work with PLAIN devices.
|
||||
* Fix create command to properly handle keyfile size.
|
||||
|
||||
2010-11-16 Milan Broz <mbroz@redhat.com>
|
||||
* Version 1.2.0-rc1.
|
||||
|
||||
2010-11-13 Milan Broz <mbroz@redhat.com>
|
||||
* Fix password callback call.
|
||||
* Fix default plain password entry from terminal in activate_by_passphrase.
|
||||
* Add --dump-master-key option for luksDump to allow volume key dump.
|
||||
* Allow to activate by internally cached volume key
|
||||
(format/activate without keyslots active - used for temporary devices).
|
||||
* Initialize volume key from active device in crypt_init_by_name()
|
||||
* Fix cryptsetup binary exitcodes.
|
||||
* Increase library version (still binary compatible with 1.1.x release).
|
||||
|
||||
2010-11-01 Milan Broz <mbroz@redhat.com>
|
||||
* No longer support luksDelKey, reload and --non-exclusive.
|
||||
* Remove some obsolete info from man page.
|
||||
* Add crypt_get_type(), crypt_resize(), crypt_keyslot_max()
|
||||
and crypt_get_active_device() to API.
|
||||
* Rewrite all implementations in cryptsetup to new API.
|
||||
* Fix luksRemoveKey to behave as documented (do not ask
|
||||
for remaining keyslot passphrase).
|
||||
* Add more regression tests for commands.
|
||||
* Disallow mapping of device which is already in use (mapped or mounted).
|
||||
* Disallow luksFormat on device in use.
|
||||
|
||||
2010-10-27 Milan Broz <mbroz@redhat.com>
|
||||
* Rewrite cryptsetup luksFormat, luksOpen, luksAddKey to use new API
|
||||
to allow adding new features.
|
||||
* Implement --use-random and --use-urandom for luksFormat to allow
|
||||
setting of RNG for volume key generator.
|
||||
* Add crypt_set_rng_type() and crypt_get_rng_type() to API.
|
||||
* Add crypt_set_uuid() to API.
|
||||
* Allow UUID setting in luksFormat and luksUUID (--uuid parameter).
|
||||
* Add --keyfile-size and --new-keyfile-size (in bytes) size and disallow overloading
|
||||
of --key-size for limiting keyfile reads.
|
||||
* Fix luksFormat to properly use key file with --master-key-file switch.
|
||||
* Fix possible double free when handling master key file.
|
||||
|
||||
2010-10-17 Milan Broz <mbroz@redhat.com>
|
||||
* Add crypt_get_device_name() to API (get underlying device name).
|
||||
* Change detection for static libraries.
|
||||
* Fix pkg-config use in automake scripts.
|
||||
* Remove --disable-shared-library switch and handle static library build
|
||||
by common libtool logic (using --enable-static).
|
||||
* Add --enable-static-cryptsetup option to build cryptsetup.static binary
|
||||
together with shared build.
|
||||
|
||||
2010-08-05 Milan Broz <mbroz@redhat.com>
|
||||
* Wipe iteration and salt after KillSlot in LUKS header.
|
||||
* Rewrite file differ test to C (and fix it to really work).
|
||||
* Switch to 1MiB default alignment of data.
|
||||
For more info see https://bugzilla.redhat.com/show_bug.cgi?id=621684
|
||||
* Do not query non-existent device twice (cryptsetup status /dev/nonexistent).
|
||||
* Check if requested hash is supported before writing LUKS header.
|
||||
|
||||
2010-07-28 Arno Wagner <arno@wagner.name>
|
||||
* Add FAQ (Frequently Asked Questions) file to distribution.
|
||||
|
||||
2010-07-03 Milan Broz <mbroz@redhat.com>
|
||||
* Fix udev support for old libdevmapper with not compatible definition.
|
||||
* Version 1.1.3.
|
||||
|
||||
2010-06-01 Milan Broz <mbroz@redhat.com>
|
||||
* Fix device alignment ioctl calls parameters.
|
||||
* Fix activate_by_* API calls to handle NULL device name as documented.
|
||||
|
||||
2010-05-30 Milan Broz <mbroz@redhat.com>
|
||||
* Version 1.1.2.
|
||||
|
||||
2010-05-27 Milan Broz <mbroz@redhat.com>
|
||||
* Fix luksFormat/luksOpen reading passphrase from stdin and "-" keyfile.
|
||||
* Support --key-file/-d option for luksFormat.
|
||||
* Fix description of --key-file and add --verbose and --debug options to man page.
|
||||
* Add verbose log level and move unlocking message there.
|
||||
* Remove device even if underlying device disappeared.
|
||||
* Fix (deprecated) reload device command to accept new device argument.
|
||||
|
||||
2010-05-23 Milan Broz <mbroz@redhat.com>
|
||||
* Fix luksClose operation for stacked DM devices.
|
||||
* Version 1.1.1.
|
||||
|
||||
2010-05-03 Milan Broz <mbroz@redhat.com>
|
||||
* Fix automatic dm-crypt module loading.
|
||||
* Escape hyphens in man page.
|
||||
* Version 1.1.1-rc2.
|
||||
|
||||
2010-04-30 Milan Broz <mbroz@redhat.com>
|
||||
* Try to use pkgconfig for device mapper library.
|
||||
* Detect old dm-crypt module and disable LUKS suspend/resume.
|
||||
* Fix apitest to work on older systems.
|
||||
* Allow no hash specification in plain device constructor.
|
||||
* Fix luksOpen reading of passphrase on stdin (if "-" keyfile specified).
|
||||
* Fix isLuks to initialise crypto backend (blkid instead is suggested anyway).
|
||||
* Version 1.1.1-rc1.
|
||||
|
||||
2010-04-12 Milan Broz <mbroz@redhat.com>
|
||||
* Fix package config to use proper package version.
|
||||
* Avoid class C++ keyword in library header.
|
||||
* Detect and use devmapper udev support if available (disable by --disable-udev).
|
||||
|
||||
2010-04-06 Milan Broz <mbroz@redhat.com>
|
||||
* Prefer some device paths in status display.
|
||||
* Support device topology detectionfor data alignment.
|
||||
|
||||
2010-02-25 Milan Broz <mbroz@redhat.com>
|
||||
* Do not verify unlocking passphrase in luksAddKey command.
|
||||
* Properly initialise crypto backend in header backup/restore commands.
|
||||
|
||||
2010-01-17 Milan Broz <mbroz@redhat.com>
|
||||
* If gcrypt compiled with capabilities, document workaround for cryptsetup (see lib/gcrypt.c).
|
||||
* Version 1.1.0.
|
||||
|
||||
2010-01-10 Milan Broz <mbroz@redhat.com>
|
||||
* Fix initialisation of gcrypt duting luksFormat.
|
||||
* Convert hash name to lower case in header (fix sha1 backward comatible header)
|
||||
* Check for minimum required gcrypt version.
|
||||
|
||||
2009-12-30 Milan Broz <mbroz@redhat.com>
|
||||
* Fix key slot iteration count calculation (small -i value was the same as default).
|
||||
* The slot and key digest iteration minimun is now 1000.
|
||||
* The key digest iteration # is calculated from iteration time (approx 1/8 of that).
|
||||
* Version 1.1.0-rc4.
|
||||
|
||||
2009-12-11 Milan Broz <mbroz@redhat.com>
|
||||
* Fix error handling during reading passhrase.
|
||||
|
||||
2009-12-01 Milan Broz <mbroz@redhat.com>
|
||||
* Allow changes of default compiled-in cipher parameters through configure.
|
||||
* Switch default key size for LUKS to 256bits.
|
||||
* Switch default plain mode to aes-cbc-essiv:sha256 (default is backward incompatible!).
|
||||
|
||||
2009-11-14 Milan Broz <mbroz@redhat.com>
|
||||
* Add CRYPT_ prefix to enum defined in libcryptsetup.h.
|
||||
* Fix status call to fail when running as non-root user.
|
||||
* Check in configure if selinux libraries are required in static version.
|
||||
* Add temporary debug code to find processes locking internal device.
|
||||
* Simplify build system, use autopoint and clean gettext processing.
|
||||
* Use proper NLS macros and detection (so the message translation works again).
|
||||
* Version 1.1.0-rc3.
|
||||
|
||||
2009-09-30 Milan Broz <mbroz@redhat.com>
|
||||
* Fix exported symbols and versions in libcryptsetup.
|
||||
* Do not use internal lib functions in cryptsetup.
|
||||
* Add crypt_log to library.
|
||||
* Fix crypt_remove_device (remove, luksClose) implementation.
|
||||
* Move dm backend initialisation to library calls.
|
||||
* Move duplicate Command failed message to verbose level (error is printed always).
|
||||
* Add some password and used algorithms notes to man page.
|
||||
* Version 1.1.0-rc2.
|
||||
|
||||
2009-09-28 Milan Broz <mbroz@redhat.com>
|
||||
* Add luksHeaderBackup and luksHeaderRestore commands.
|
||||
* Fail passphrase read if piped input no longer exists.
|
||||
* Version 1.1.0-rc1.
|
||||
|
||||
2009-09-15 Milan Broz <mbroz@redhat.com>
|
||||
* Initialize crypto library before LUKS header load.
|
||||
* Fix manpage to not require --size which expands to device size by default.
|
||||
|
||||
2009-09-10 Milan Broz <mbroz@redhat.com>
|
||||
* Clean up Makefiles and configure script.
|
||||
* Version 1.1.0-test0.
|
||||
|
||||
2009-09-08 Milan Broz <mbroz@redhat.com>
|
||||
* Use dm-uuid for all crypt devices, contains device type and name now.
|
||||
* Try to read first sector from device to properly check that device is ready.
|
||||
|
||||
2009-09-02 Milan Broz <mbroz@redhat.com>
|
||||
* Add luksSuspend (freeze device and wipe key) and luksResume (with provided passphrase).
|
||||
|
||||
2009-08-30 Milan Broz <mbroz@redhat.com>
|
||||
* Require device device-mapper to build and do not use backend wrapper for dm calls.
|
||||
* Move memory locking and dm initialization to command layer.
|
||||
* Increase priority of process if memory is locked.
|
||||
* Add log macros and make logging modre consitent.
|
||||
* Move command successful messages to verbose level.
|
||||
* Introduce --debug parameter.
|
||||
* Move device utils code and provide context parameter (for log).
|
||||
* Keyfile now must be provided by path, only stdin file descriptor is used (api only).
|
||||
* Do not call isatty() on closed keyfile descriptor.
|
||||
* Run performance check for PBKDF2 from LUKS code, do not mix hash algoritms results.
|
||||
* Add ability to provide pre-generated master key and UUID in LUKS header format.
|
||||
* Add LUKS function to verify master key digest.
|
||||
* Move key slot manuipulation function into LUKS specific code.
|
||||
* Replace global options struct with separate parameters in helper functions.
|
||||
* Add new libcryptsetup API (documented in libcryptsetup.h).
|
||||
* Implement old API calls using new functions.
|
||||
* Remove old API code helper functions.
|
||||
* Add --master-key-file option for luksFormat and luksAddKey.
|
||||
|
||||
2009-08-17 Milan Broz <mbroz@redhat.com>
|
||||
* Fix PBKDF2 speed calculation for large passhrases.
|
||||
* Allow using passphrase provided in options struct for LuksOpen.
|
||||
* Allow restrict keys size in LuksOpen.
|
||||
|
||||
2009-07-30 Milan Broz <mbroz@redhat.com>
|
||||
* Fix errors when compiled with LUKS_DEBUG.
|
||||
* Print error when getline fails.
|
||||
* Remove po/cryptsetup-luks.pot, it's autogenerated.
|
||||
* Return ENOENT for empty keyslots, EINVAL will be used later for other type of error.
|
||||
* Switch PBKDF2 from internal SHA1 to libgcrypt, make hash algorithm not hardcoded to SHA1 here.
|
||||
* Add required parameters for changing hash used in LUKS key setup scheme.
|
||||
* Do not export simple XOR helper now used only inside AF functions.
|
||||
* Completely remove internal SHA1 implementanion code, not needed anymore.
|
||||
* Enable hash algorithm selection for LUKS through -h luksFormat option.
|
||||
|
||||
2009-07-28 Milan Broz <mbroz@redhat.com>
|
||||
* Pad luks header to 512 sector size.
|
||||
* Rework read/write blockwise to not split operation to many pieces.
|
||||
* Use posix_memalign if available.
|
||||
|
||||
2009-07-22 Milan Broz <mbroz@redhat.com>
|
||||
* Fix segfault if provided slot in luksKillslot is invalid.
|
||||
* Remove unneeded timeout when remove of temporary device succeeded.
|
||||
|
||||
2009-07-22 Milan Broz <mbroz@redhat.com>
|
||||
* version 1.0.7
|
||||
|
||||
@@ -82,7 +499,7 @@
|
||||
* configure.in (AC_OUTPUT): Add m4/Makefile.
|
||||
(AM_GNU_GETTEXT_VERSION): Bump to 0.15.
|
||||
|
||||
2006-10-22 David H<EFBFBD>rdeman <david@hardeman.nu>
|
||||
2006-10-22 David Härdeman <david@hardeman.nu>
|
||||
|
||||
* Allow hashing of keys passed through stdin.
|
||||
|
||||
@@ -149,7 +566,7 @@
|
||||
|
||||
2006-08-04 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* lib/setup.c (get_key): Applied patch from David H<EFBFBD>rdeman
|
||||
* lib/setup.c (get_key): Applied patch from David Härdeman
|
||||
<david@2gen.com> for reading binary keys from stdin using
|
||||
the "-" as key file.
|
||||
|
||||
@@ -166,7 +583,7 @@
|
||||
|
||||
2006-07-23 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
* Applied patches from David H<EFBFBD>rdeman <david@2gen.com> to fix 64
|
||||
* Applied patches from David Härdeman <david@2gen.com> to fix 64
|
||||
bit compiler warning issues.
|
||||
|
||||
2006-05-19 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
@@ -185,7 +602,7 @@
|
||||
|
||||
* configure.in: Release 1.0.3.
|
||||
|
||||
* Applied patch by Johannes Wei<EFBFBD>l for more meaningful exit codes
|
||||
* Applied patch by Johannes Weißl for more meaningful exit codes
|
||||
and password retries
|
||||
|
||||
2006-03-30 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
EXTRA_DIST = COPYING.LGPL FAQ docs misc
|
||||
SUBDIRS = \
|
||||
luks \
|
||||
lib \
|
||||
src \
|
||||
man \
|
||||
python \
|
||||
tests \
|
||||
po
|
||||
|
||||
ACLOCAL_AMFLAGS = -I m4
|
||||
|
||||
clean-local:
|
||||
-rm -rf docs/doxygen_api_docs
|
||||
|
||||
31
README
31
README
@@ -0,0 +1,31 @@
|
||||
|
||||
cryptsetup
|
||||
|
||||
setup cryptographic volumes for dm-crypt (including LUKS extension)
|
||||
|
||||
WEB PAGE:
|
||||
|
||||
http://code.google.com/p/cryptsetup/
|
||||
|
||||
FAQ:
|
||||
|
||||
http://code.google.com/p/cryptsetup/wiki/FrequentlyAskedQuestions
|
||||
|
||||
MAILING LIST:
|
||||
|
||||
E-MAIL: dm-crypt@saout.de
|
||||
URL: http://www.saout.de/mailman/listinfo/dm-crypt
|
||||
|
||||
DOWNLOAD:
|
||||
|
||||
http://code.google.com/p/cryptsetup/downloads/
|
||||
|
||||
SOURCE CODE:
|
||||
|
||||
URL: http://code.google.com/p/cryptsetup/source/browse/
|
||||
Checkout: git clone https://code.google.com/p/cryptsetup/
|
||||
|
||||
NLS (PO TRANSLATIONS):
|
||||
|
||||
PO files are maintained by:
|
||||
http://translationproject.org/domain/cryptsetup.html
|
||||
|
||||
19
TODO
19
TODO
@@ -1,12 +1,7 @@
|
||||
For 1.02
|
||||
|
||||
* Add LUKS key copy cmd: luksKeyCopy
|
||||
* Add option to supply a master key directly. For LUKS commands: luksFormat, luksOpen and luksAddKey.
|
||||
|
||||
For 2.0
|
||||
|
||||
* LUKS header version bump:
|
||||
* Add LUKS partition footer.
|
||||
* change luks_write_phdr stuff.
|
||||
* change luks_read_phdr stuff
|
||||
* change hashing according to conversation with Sarah.
|
||||
Version 1.6.0:
|
||||
- Export wipe device functions
|
||||
- Support K/M suffixes for align payload (new switch?).
|
||||
- FIPS: move changekey to library
|
||||
- online reencryption api?
|
||||
- integrate more metadata formats
|
||||
- TRIM for keyslots
|
||||
|
||||
53
acinclude.m4
53
acinclude.m4
@@ -1,53 +0,0 @@
|
||||
dnl MODULE_HELPER(NAME, HELP, DEFAULT, COMMANDS)
|
||||
AC_DEFUN([MODULE_HELPER],[
|
||||
unset have_module
|
||||
AC_ARG_ENABLE([$1], [$2],,[
|
||||
if test "x${enable_all}" = "xdefault"; then
|
||||
enable_[$1]=[$3]
|
||||
else
|
||||
enable_[$1]="${enable_all}"
|
||||
fi
|
||||
])
|
||||
if test "x${enable_[$1]}" != "xno"; then
|
||||
$4
|
||||
AC_MSG_CHECKING([whether to build $1 module])
|
||||
if test -n "${have_module+set}"; then
|
||||
if test "x${enable_[$1]}" = "xauto"; then
|
||||
if test "x${enable_plugins}" != "xno"; then
|
||||
AC_MSG_RESULT([yes, as plugin])
|
||||
build_static=no
|
||||
build_shared=yes
|
||||
else
|
||||
AC_MSG_RESULT([yes])
|
||||
build_static=yes
|
||||
build_shared=no
|
||||
fi
|
||||
elif test "x${enable_[$1]}" = "xshared"; then
|
||||
if test "x${enable_plugins}" != "xno"; then
|
||||
AC_MSG_RESULT([yes, as plugin])
|
||||
build_static=no
|
||||
build_shared=yes
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
AC_MSG_ERROR([Can't build [$1] module, plugins are disabled])
|
||||
fi
|
||||
else
|
||||
AC_MSG_RESULT([yes])
|
||||
build_static=yes
|
||||
build_shared=no
|
||||
fi
|
||||
elif test "x${enable_[$1]}" != "xauto"; then
|
||||
AC_MSG_RESULT([no])
|
||||
AC_MSG_ERROR([Unable to build $1 plugin, see messages above])
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
build_static=no
|
||||
build_shared=no
|
||||
fi
|
||||
else
|
||||
AC_MSG_CHECKING([whether to build $1 module])
|
||||
AC_MSG_RESULT([no])
|
||||
build_static=no
|
||||
build_shared=no
|
||||
fi
|
||||
])
|
||||
98
autogen.sh
98
autogen.sh
@@ -2,13 +2,21 @@
|
||||
# Run this to generate all the initial makefiles, etc.
|
||||
|
||||
srcdir=`dirname $0`
|
||||
PKG_NAME="the package."
|
||||
PKG_NAME="cryptsetup"
|
||||
|
||||
DIE=0
|
||||
|
||||
(autopoint --version) < /dev/null > /dev/null 2>&1 || {
|
||||
echo
|
||||
echo "**Error**: You must have autopoint installed."
|
||||
echo "Download the appropriate package for your distribution,"
|
||||
echo "or see http://www.gnu.org/software/gettext"
|
||||
DIE=1
|
||||
}
|
||||
|
||||
(autoconf --version) < /dev/null > /dev/null 2>&1 || {
|
||||
echo
|
||||
echo "**Error**: You must have \`autoconf' installed to."
|
||||
echo "**Error**: You must have autoconf installed to."
|
||||
echo "Download the appropriate package for your distribution,"
|
||||
echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/"
|
||||
DIE=1
|
||||
@@ -17,7 +25,7 @@ DIE=0
|
||||
(grep "^AM_PROG_LIBTOOL" $srcdir/configure.in >/dev/null) && {
|
||||
(libtool --version) < /dev/null > /dev/null 2>&1 || {
|
||||
echo
|
||||
echo "**Error**: You must have \`libtool' installed."
|
||||
echo "**Error**: You must have libtool installed."
|
||||
echo "Get ftp://ftp.gnu.org/pub/gnu/"
|
||||
echo "(or a newer version if it is available)"
|
||||
DIE=1
|
||||
@@ -26,7 +34,7 @@ DIE=0
|
||||
|
||||
(automake --version) < /dev/null > /dev/null 2>&1 || {
|
||||
echo
|
||||
echo "**Error**: You must have \`automake' installed."
|
||||
echo "**Error**: You must have automake installed."
|
||||
echo "Get ftp://ftp.gnu.org/pub/gnu/"
|
||||
echo "(or a newer version if it is available)"
|
||||
DIE=1
|
||||
@@ -37,7 +45,7 @@ DIE=0
|
||||
# if no automake, don't bother testing for aclocal
|
||||
test -n "$NO_AUTOMAKE" || (aclocal --version) < /dev/null > /dev/null 2>&1 || {
|
||||
echo
|
||||
echo "**Error**: Missing \`aclocal'. The version of \`automake'"
|
||||
echo "**Error**: Missing aclocal. The version of automake"
|
||||
echo "installed doesn't appear recent enough."
|
||||
echo "Get ftp://ftp.gnu.org/pub/gnu/"
|
||||
echo "(or a newer version if it is available)"
|
||||
@@ -49,73 +57,29 @@ if test "$DIE" -eq 1; then
|
||||
fi
|
||||
|
||||
if test -z "$*"; then
|
||||
echo "**Warning**: I am going to run \`configure' with no arguments."
|
||||
echo "If you wish to pass any to it, please specify them on the"
|
||||
echo \`$0\'" command line."
|
||||
echo
|
||||
echo "**Warning**: I am going to run 'configure' with no arguments."
|
||||
echo "If you wish to pass any to it, please specify them on the"
|
||||
echo \'$0\'" command line."
|
||||
fi
|
||||
|
||||
case $CC in
|
||||
xlc )
|
||||
am_opt=--include-deps;;
|
||||
esac
|
||||
echo
|
||||
echo "Generate build-system by:"
|
||||
echo " autopoint: $(autopoint --version | head -1)"
|
||||
echo " aclocal: $(aclocal --version | head -1)"
|
||||
echo " autoconf: $(autoconf --version | head -1)"
|
||||
echo " automake: $(automake --version | head -1)"
|
||||
echo " libtoolize: $(libtoolize --version | head -1)"
|
||||
echo
|
||||
|
||||
for coin in `find $srcdir -name configure.in -a \( ! -regex '.*/\..*' \) -print`
|
||||
do
|
||||
dr=`dirname $coin`
|
||||
if test -f $dr/NO-AUTO-GEN; then
|
||||
echo skipping $dr -- flagged as no auto-gen
|
||||
else
|
||||
echo processing $dr
|
||||
macrodirs=`sed -n -e 's,AM_ACLOCAL_INCLUDE(\(.*\)),\1,gp' < $coin`
|
||||
( cd $dr
|
||||
aclocalinclude="$ACLOCAL_FLAGS"
|
||||
for k in $macrodirs; do
|
||||
if test -d $k; then
|
||||
aclocalinclude="$aclocalinclude -I $k"
|
||||
##else
|
||||
## echo "**Warning**: No such directory \`$k'. Ignored."
|
||||
fi
|
||||
done
|
||||
if grep "^AM_GNU_GETTEXT" configure.in >/dev/null; then
|
||||
if grep "sed.*POTFILES" configure.in >/dev/null; then
|
||||
: do nothing -- we still have an old unmodified configure.in
|
||||
else
|
||||
echo "Creating $dr/aclocal.m4 ..."
|
||||
test -r $dr/aclocal.m4 || touch $dr/aclocal.m4
|
||||
echo "Running gettextize... Ignore non-fatal messages."
|
||||
./setup-gettext
|
||||
echo "Making $dr/aclocal.m4 writable ..."
|
||||
test -r $dr/aclocal.m4 && chmod u+w $dr/aclocal.m4
|
||||
fi
|
||||
fi
|
||||
if grep "^AM_GNOME_GETTEXT" configure.in >/dev/null; then
|
||||
echo "Creating $dr/aclocal.m4 ..."
|
||||
test -r $dr/aclocal.m4 || touch $dr/aclocal.m4
|
||||
echo "Running gettextize... Ignore non-fatal messages."
|
||||
./setup-gettext
|
||||
echo "Making $dr/aclocal.m4 writable ..."
|
||||
test -r $dr/aclocal.m4 && chmod u+w $dr/aclocal.m4
|
||||
fi
|
||||
if grep "^AM_PROG_LIBTOOL" configure.in >/dev/null; then
|
||||
echo "Running libtoolize..."
|
||||
libtoolize --force --copy
|
||||
fi
|
||||
echo "Running aclocal $aclocalinclude ..."
|
||||
aclocal $aclocalinclude
|
||||
if grep "^AM_CONFIG_HEADER" configure.in >/dev/null; then
|
||||
echo "Running autoheader..."
|
||||
autoheader
|
||||
fi
|
||||
echo "Running automake --gnu $am_opt ..."
|
||||
automake --add-missing --gnu $am_opt
|
||||
echo "Running autoconf ..."
|
||||
autoconf
|
||||
)
|
||||
fi
|
||||
done
|
||||
|
||||
#conf_flags="--enable-maintainer-mode --enable-compile-warnings" #--enable-iso-c
|
||||
set -e
|
||||
autopoint --force $AP_OPTS
|
||||
libtoolize --force --copy
|
||||
aclocal -I m4 $AL_OPTS
|
||||
autoheader $AH_OPTS
|
||||
automake --add-missing --gnu $AM_OPTS
|
||||
autoconf $AC_OPTS
|
||||
|
||||
if test x$NOCONFIGURE = x; then
|
||||
echo Running $srcdir/configure $conf_flags "$@" ...
|
||||
|
||||
393
configure.in
393
configure.in
@@ -1,8 +1,16 @@
|
||||
AC_PREREQ(2.57)
|
||||
AC_INIT(cryptsetup,1.0.7)
|
||||
AC_CONFIG_SRCDIR(src/cryptsetup.c)
|
||||
AC_PREREQ([2.67])
|
||||
AC_INIT([cryptsetup],[1.5.0])
|
||||
|
||||
AM_CONFIG_HEADER([config.h:config.h.in])
|
||||
dnl library version from <major>.<minor>.<release>[-<suffix>]
|
||||
LIBCRYPTSETUP_VERSION=$(echo $PACKAGE_VERSION | cut -f1 -d-)
|
||||
LIBCRYPTSETUP_VERSION_INFO=7:0:3
|
||||
dnl library file name for FIPS selfcheck
|
||||
LIBCRYPTSETUP_VERSION_FIPS="libcryptsetup.so.4"
|
||||
|
||||
AC_CONFIG_SRCDIR(src/cryptsetup.c)
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
|
||||
AC_CONFIG_HEADERS([config.h:config.h.in])
|
||||
AM_INIT_AUTOMAKE(dist-bzip2)
|
||||
|
||||
if test "x$prefix" = "xNONE"; then
|
||||
@@ -11,35 +19,33 @@ fi
|
||||
AC_PREFIX_DEFAULT(/usr)
|
||||
|
||||
AC_CANONICAL_HOST
|
||||
AC_GNU_SOURCE
|
||||
AC_USE_SYSTEM_EXTENSIONS
|
||||
AC_PROG_CC
|
||||
AM_PROG_CC_C_O
|
||||
AC_PROG_CPP
|
||||
AC_PROG_INSTALL
|
||||
AC_PROG_MAKE_SET
|
||||
AC_ENABLE_STATIC(no)
|
||||
AM_PROG_LIBTOOL
|
||||
LT_INIT
|
||||
|
||||
AC_HEADER_DIRENT
|
||||
AC_HEADER_STDC
|
||||
AC_CHECK_HEADERS(fcntl.h malloc.h inttypes.h sys/ioctl.h sys/mman.h \
|
||||
ctype.h unistd.h locale.h)
|
||||
|
||||
AC_CHECK_HEADERS(uuid/uuid.h,,[AC_MSG_ERROR('You need the uuid library (from e2fsprogs)')])
|
||||
AC_CHECK_HEADERS(uuid/uuid.h,,[AC_MSG_ERROR([You need the uuid library.])])
|
||||
AC_CHECK_HEADER(libdevmapper.h,,[AC_MSG_ERROR([You need the device-mapper library.])])
|
||||
|
||||
saved_LIBS="$LIBS"
|
||||
AC_CHECK_LIB(uuid, uuid_clear, ,[AC_MSG_ERROR('You need the uuid library (from e2fsprogs)')])
|
||||
UUID_LIBS="$LIBS"
|
||||
LIBS="$saved_LIBS"
|
||||
AC_SUBST(UUID_LIBS)
|
||||
|
||||
AC_CHECK_FUNCS(setlocale)
|
||||
saved_LIBS=$LIBS
|
||||
AC_CHECK_LIB(uuid, uuid_clear, ,[AC_MSG_ERROR([You need the uuid library.])])
|
||||
AC_SUBST(UUID_LIBS, $LIBS)
|
||||
LIBS=$saved_LIBS
|
||||
|
||||
AC_CHECK_FUNCS([posix_memalign])
|
||||
|
||||
AC_C_CONST
|
||||
AC_C_BIGENDIAN
|
||||
AC_TYPE_OFF_T
|
||||
AC_STRUCT_ST_RDEV
|
||||
AC_SYS_LARGEFILE
|
||||
|
||||
AC_PROG_GCC_TRADITIONAL
|
||||
@@ -51,83 +57,320 @@ AM_GNU_GETTEXT_VERSION([0.15])
|
||||
|
||||
dnl ==========================================================================
|
||||
|
||||
saved_LIBS="$LIBS"
|
||||
saved_LIBS=$LIBS
|
||||
AC_CHECK_LIB(popt, poptConfigFileToString,,
|
||||
AC_MSG_ERROR([You need popt 1.7 or newer to compile.]))
|
||||
POPT_LIBS="$LIBS"
|
||||
LIBS="$saved_LIBS"
|
||||
AC_SUBST(POPT_LIBS)
|
||||
[AC_MSG_ERROR([You need popt 1.7 or newer to compile.])])
|
||||
AC_SUBST(POPT_LIBS, $LIBS)
|
||||
LIBS=$saved_LIBS
|
||||
|
||||
dnl ==========================================================================
|
||||
dnl FIPS extensions
|
||||
AC_ARG_ENABLE([fips], AS_HELP_STRING([--enable-fips],[enable FIPS mode restrictions]),
|
||||
[with_fips=$enableval],
|
||||
[with_fips=no])
|
||||
|
||||
AC_ARG_ENABLE(shared-library,
|
||||
[ --disable-shared-library
|
||||
disable building of shared cryptsetup library],,
|
||||
enable_shared_library=yes)
|
||||
AM_CONDITIONAL(STATIC_LIBRARY, test x$enable_shared_library = xno)
|
||||
if test "x$with_fips" = "xyes"; then
|
||||
AC_DEFINE(ENABLE_FIPS, 1, [Enable FIPS mode restrictions])
|
||||
AC_DEFINE_UNQUOTED(LIBCRYPTSETUP_VERSION_FIPS, ["$LIBCRYPTSETUP_VERSION_FIPS"],
|
||||
[library file name for FIPS selfcheck])
|
||||
|
||||
if test "x$enable_static" = "xyes" -o "x$enable_static_cryptsetup" = "xyes" ; then
|
||||
AC_MSG_ERROR([Static build is not compatible with FIPS.])
|
||||
fi
|
||||
|
||||
saved_LIBS=$LIBS
|
||||
AC_CHECK_LIB(fipscheck, FIPSCHECK_verify, ,[AC_MSG_ERROR([You need the fipscheck library.])])
|
||||
AC_SUBST(FIPSCHECK_LIBS, $LIBS)
|
||||
LIBS=$saved_LIBS
|
||||
|
||||
AC_ARG_ENABLE(plugins,
|
||||
[ --enable-plugins disable shared library plugins],,enable_plugins=no)
|
||||
if test "x$enable_plugins" = xyes; then
|
||||
AC_DEFINE(USE_PLUGINS, 1, [Define if you wish to use the plugin loader])
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(, [
|
||||
Modules:
|
||||
--with-MODULE[[=shared]] builds the module MODULE as a shared library plugin
|
||||
],,)
|
||||
|
||||
AC_ARG_ENABLE(all,
|
||||
[ --disable-all disable all modules built by default],,enable_all=default)
|
||||
|
||||
MODULE_HELPER(libgcrypt,
|
||||
[ --enable-libgcrypt enable libgcrypt crypto functions [[default=auto]]],auto,[
|
||||
AM_PATH_LIBGCRYPT(1.1.42,have_module=yes)
|
||||
AC_DEFUN([NO_FIPS], [
|
||||
if test "x$with_fips" = "xyes"; then
|
||||
AC_MSG_ERROR([This option is not compatible with FIPS.])
|
||||
fi
|
||||
])
|
||||
AM_CONDITIONAL(BUILD_LIBGCRYPT, test x$build_static = xyes)
|
||||
AM_CONDITIONAL(SHARED_LIBGCRYPT, test x$build_shared = xyes)
|
||||
|
||||
dnl ==========================================================================
|
||||
dnl Crypto backend functions
|
||||
|
||||
AC_DEFUN([CONFIGURE_GCRYPT], [
|
||||
if test "x$with_fips" = "xyes"; then
|
||||
GCRYPT_REQ_VERSION=1.4.5
|
||||
else
|
||||
GCRYPT_REQ_VERSION=1.1.42
|
||||
fi
|
||||
AM_PATH_LIBGCRYPT($GCRYPT_REQ_VERSION,,[AC_MSG_ERROR([You need the gcrypt library.])])
|
||||
|
||||
if test x$enable_static_cryptsetup = xyes; then
|
||||
saved_LIBS=$LIBS
|
||||
LIBS="$saved_LIBS $LIBGCRYPT_LIBS -static"
|
||||
AC_CHECK_LIB(gcrypt, gcry_check_version,,
|
||||
AC_MSG_ERROR([Cannot find static gcrypt library.]),
|
||||
[-lgpg-error])
|
||||
LIBGCRYPT_STATIC_LIBS="$LIBGCRYPT_LIBS -lgpg-error"
|
||||
LIBS=$saved_LIBS
|
||||
fi
|
||||
|
||||
CRYPTO_CFLAGS=$LIBGCRYPT_CFLAGS
|
||||
CRYPTO_LIBS=$LIBGCRYPT_LIBS
|
||||
CRYPTO_STATIC_LIBS=$LIBGCRYPT_STATIC_LIBS
|
||||
|
||||
AC_DEFINE_UNQUOTED(GCRYPT_REQ_VERSION, ["$GCRYPT_REQ_VERSION"], [Requested gcrypt version])
|
||||
])
|
||||
|
||||
AC_DEFUN([CONFIGURE_OPENSSL], [
|
||||
PKG_CHECK_MODULES([OPENSSL], [openssl >= 0.9.8],,
|
||||
AC_MSG_ERROR([You need openssl library.]))
|
||||
CRYPTO_CFLAGS=$OPENSSL_CFLAGS
|
||||
CRYPTO_LIBS=$OPENSSL_LIBS
|
||||
|
||||
if test x$enable_static_cryptsetup = xyes; then
|
||||
saved_PKG_CONFIG=$PKG_CONFIG
|
||||
PKG_CONFIG="$PKG_CONFIG --static"
|
||||
PKG_CHECK_MODULES([OPENSSL], [openssl])
|
||||
CRYPTO_STATIC_LIBS=$OPENSSL_LIBS
|
||||
PKG_CONFIG=$saved_PKG_CONFIG
|
||||
fi
|
||||
NO_FIPS([])
|
||||
])
|
||||
|
||||
AC_DEFUN([CONFIGURE_NSS], [
|
||||
if test x$enable_static_cryptsetup = xyes; then
|
||||
AC_MSG_ERROR([Static build of cryptsetup is not supported with NSS.])
|
||||
fi
|
||||
|
||||
AC_MSG_WARN([NSS backend does NOT provide backward compatibility (missing ripemd160 hash).])
|
||||
|
||||
PKG_CHECK_MODULES([NSS], [nss],,
|
||||
AC_MSG_ERROR([You need nss library.]))
|
||||
|
||||
saved_CFLAGS=$CFLAGS
|
||||
CFLAGS="$CFLAGS $NSS_CFLAGS"
|
||||
AC_CHECK_DECLS([NSS_GetVersion], [], [], [#include <nss.h>])
|
||||
CFLAGS=$saved_CFLAGS
|
||||
|
||||
CRYPTO_CFLAGS=$NSS_CFLAGS
|
||||
CRYPTO_LIBS=$NSS_LIBS
|
||||
NO_FIPS([])
|
||||
])
|
||||
|
||||
AC_DEFUN([CONFIGURE_KERNEL], [
|
||||
AC_CHECK_HEADERS(linux/if_alg.h,,
|
||||
[AC_MSG_ERROR([You need Linux kernel with userspace crypto interface.])])
|
||||
# AC_CHECK_DECLS([AF_ALG],,
|
||||
# [AC_MSG_ERROR([You need Linux kernel with userspace crypto interface.])],
|
||||
# [#include <sys/socket.h>])
|
||||
NO_FIPS([])
|
||||
])
|
||||
|
||||
AC_DEFUN([CONFIGURE_NETTLE], [
|
||||
AC_CHECK_HEADERS(nettle/sha.h,,
|
||||
[AC_MSG_ERROR([You need Nettle cryptographic library.])])
|
||||
|
||||
saved_LIBS=$LIBS
|
||||
AC_CHECK_LIB(nettle, nettle_ripemd160_init,,
|
||||
[AC_MSG_ERROR([You need Nettle library version 2.4 or more recent.])])
|
||||
CRYPTO_LIBS=$LIBS
|
||||
LIBS=$saved_LIBS
|
||||
|
||||
CRYPTO_STATIC_LIBS=$CRYPTO_LIBS
|
||||
NO_FIPS([])
|
||||
])
|
||||
|
||||
dnl ==========================================================================
|
||||
saved_LIBS=$LIBS
|
||||
|
||||
AC_ARG_ENABLE([static-cryptsetup],
|
||||
AS_HELP_STRING([--enable-static-cryptsetup],
|
||||
[enable build of static cryptsetup binary]))
|
||||
if test x$enable_static_cryptsetup = xyes; then
|
||||
if test x$enable_static = xno; then
|
||||
AC_MSG_WARN([Requested static cryptsetup build, enabling static library.])
|
||||
enable_static=yes
|
||||
fi
|
||||
fi
|
||||
AM_CONDITIONAL(STATIC_TOOLS, test x$enable_static_cryptsetup = xyes)
|
||||
|
||||
AC_ARG_ENABLE(veritysetup,
|
||||
AS_HELP_STRING([--disable-veritysetup],
|
||||
[disable veritysetup support]),[], [enable_veritysetup=yes])
|
||||
AM_CONDITIONAL(VERITYSETUP, test x$enable_veritysetup = xyes)
|
||||
|
||||
AC_ARG_ENABLE([cryptsetup-reencrypt],
|
||||
AS_HELP_STRING([--enable-cryptsetup-reencrypt],
|
||||
[enable cryptsetup-reencrypt tool]))
|
||||
AM_CONDITIONAL(REENCRYPT, test x$enable_cryptsetup_reencrypt = xyes)
|
||||
|
||||
AC_ARG_ENABLE(selinux,
|
||||
[ --disable-selinux disable selinux support [[default=auto]]],[], [])
|
||||
AS_HELP_STRING([--disable-selinux],
|
||||
[disable selinux support [default=auto]]),[], [])
|
||||
|
||||
MODULE_HELPER(libdevmapper,
|
||||
[ --enable-libdevmapper enable dm-crypt backend through libdevmapper
|
||||
[[default=auto]]],auto,[
|
||||
have_module=yes
|
||||
saved_LIBS="$LIBS"
|
||||
if test "x$enable_selinux" != xno; then
|
||||
AC_CHECK_LIB(sepol, sepol_bool_set)
|
||||
AC_CHECK_LIB(selinux, is_selinux_enabled)
|
||||
# Check if we need -pthread with --enable-static and selinux
|
||||
if test x$build_static = xyes; then
|
||||
saved_LIBS2="$LIBS"
|
||||
LIBS="$LIBS -static"
|
||||
AC_SEARCH_LIBS([pthread_mutex_lock], [pthread],
|
||||
[test "$ac_cv_search_pthread_mutex_lock" = "none required" || LIB_PTHREAD=-lpthread])
|
||||
LIBS="$saved_LIBS2"
|
||||
fi
|
||||
fi
|
||||
AC_CHECK_LIB(devmapper, dm_task_set_name,,unset have_module)
|
||||
AC_CHECK_HEADER(libdevmapper.h,,unset have_module)
|
||||
LIBDEVMAPPER_LIBS="$LIBS $LIB_PTHREAD"
|
||||
LIBS="$saved_LIBS"
|
||||
AC_SUBST(LIBDEVMAPPER_LIBS)
|
||||
AC_SUBST(LIBDEVMAPPER_CFLAGS)
|
||||
AC_ARG_ENABLE([udev],
|
||||
AS_HELP_STRING([--disable-udev],
|
||||
[disable udev support]),[], enable_udev=yes)
|
||||
|
||||
dnl Try to use pkg-config for devmapper, but fallback to old detection
|
||||
PKG_CHECK_MODULES([DEVMAPPER], [devmapper >= 1.02.03],, [
|
||||
AC_CHECK_LIB(devmapper, dm_task_set_name,,
|
||||
[AC_MSG_ERROR([You need the device-mapper library.])])
|
||||
AC_CHECK_LIB(devmapper, dm_task_set_message,,
|
||||
[AC_MSG_ERROR([The device-mapper library on your system is too old.])])
|
||||
DEVMAPPER_LIBS=$LIBS
|
||||
])
|
||||
AM_CONDITIONAL(BUILD_LIBDEVMAPPER, test x$build_static = xyes)
|
||||
AM_CONDITIONAL(SHARED_LIBDEVMAPPER, test x$build_shared = xyes)
|
||||
LIBS=$saved_LIBS
|
||||
|
||||
LIBS="$LIBS $DEVMAPPER_LIBS"
|
||||
AC_CHECK_DECLS([dm_task_secure_data], [], [], [#include <libdevmapper.h>])
|
||||
AC_CHECK_DECLS([dm_task_retry_remove], [], [], [#include <libdevmapper.h>])
|
||||
AC_CHECK_DECLS([DM_UDEV_DISABLE_DISK_RULES_FLAG], [have_cookie=yes], [have_cookie=no], [#include <libdevmapper.h>])
|
||||
if test "x$enable_udev" = xyes; then
|
||||
if test "x$have_cookie" = xno; then
|
||||
AC_MSG_WARN([The device-mapper library on your system has no udev support, udev support disabled.])
|
||||
else
|
||||
AC_DEFINE(USE_UDEV, 1, [Try to use udev synchronisation?])
|
||||
fi
|
||||
fi
|
||||
LIBS=$saved_LIBS
|
||||
|
||||
dnl Crypto backend configuration.
|
||||
AC_ARG_WITH([crypto_backend],
|
||||
AS_HELP_STRING([--with-crypto_backend=BACKEND], [crypto backend (gcrypt/openssl/nss/kernel/nettle) [gcrypt]]),
|
||||
[], with_crypto_backend=gcrypt
|
||||
)
|
||||
case $with_crypto_backend in
|
||||
gcrypt) CONFIGURE_GCRYPT([]) ;;
|
||||
openssl) CONFIGURE_OPENSSL([]) ;;
|
||||
nss) CONFIGURE_NSS([]) ;;
|
||||
kernel) CONFIGURE_KERNEL([]) ;;
|
||||
nettle) CONFIGURE_NETTLE([]) ;;
|
||||
*) AC_MSG_ERROR([Unknown crypto backend.]) ;;
|
||||
esac
|
||||
AM_CONDITIONAL(CRYPTO_BACKEND_GCRYPT, test $with_crypto_backend = gcrypt)
|
||||
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)
|
||||
|
||||
dnl Magic for cryptsetup.static build.
|
||||
if test x$enable_static_cryptsetup = xyes; then
|
||||
saved_PKG_CONFIG=$PKG_CONFIG
|
||||
PKG_CONFIG="$PKG_CONFIG --static"
|
||||
|
||||
LIBS="$saved_LIBS -static"
|
||||
AC_CHECK_LIB(popt, poptGetContext,,
|
||||
AC_MSG_ERROR([Cannot find static popt library.]))
|
||||
|
||||
dnl Try to detect needed device-mapper static libraries, try pkg-config first.
|
||||
LIBS="$saved_LIBS -static"
|
||||
PKG_CHECK_MODULES([DEVMAPPER_STATIC], [devmapper >= 1.02.27],,[
|
||||
DEVMAPPER_STATIC_LIBS=$DEVMAPPER_LIBS
|
||||
if test "x$enable_selinux" != xno; then
|
||||
AC_CHECK_LIB(sepol, sepol_bool_set)
|
||||
AC_CHECK_LIB(selinux, is_selinux_enabled)
|
||||
DEVMAPPER_STATIC_LIBS="$DEVMAPPER_STATIC_LIBS $LIBS"
|
||||
fi
|
||||
])
|
||||
LIBS="$saved_LIBS $DEVMAPPER_STATIC_LIBS"
|
||||
AC_CHECK_LIB(devmapper, dm_task_set_uuid,,
|
||||
AC_MSG_ERROR([Cannot link with static device-mapper library.]))
|
||||
|
||||
dnl Try to detect uuid static library.
|
||||
LIBS="$saved_LIBS -static"
|
||||
AC_CHECK_LIB(uuid, uuid_generate,,
|
||||
AC_MSG_ERROR([Cannot find static uuid library.]))
|
||||
|
||||
LIBS=$saved_LIBS
|
||||
PKG_CONFIG=$saved_PKG_CONFIG
|
||||
fi
|
||||
|
||||
AC_SUBST([DEVMAPPER_LIBS])
|
||||
AC_SUBST([DEVMAPPER_STATIC_LIBS])
|
||||
|
||||
AC_SUBST([CRYPTO_CFLAGS])
|
||||
AC_SUBST([CRYPTO_LIBS])
|
||||
AC_SUBST([CRYPTO_STATIC_LIBS])
|
||||
|
||||
AC_SUBST([LIBCRYPTSETUP_VERSION])
|
||||
AC_SUBST([LIBCRYPTSETUP_VERSION_INFO])
|
||||
AC_SUBST([LIBCRYPTSETUP_VERSION_FIPS])
|
||||
|
||||
dnl ==========================================================================
|
||||
AC_ARG_ENABLE([dev-random], AS_HELP_STRING([--enable-dev-random],
|
||||
[use blocking /dev/random by default for key generator (otherwise use /dev/urandom)]),
|
||||
[default_rng=/dev/random], [default_rng=/dev/urandom])
|
||||
AC_DEFINE_UNQUOTED(DEFAULT_RNG, ["$default_rng"], [default RNG type for key generator])
|
||||
|
||||
dnl ==========================================================================
|
||||
AC_DEFUN([CS_DEFINE],
|
||||
[AC_DEFINE_UNQUOTED(DEFAULT_[]m4_translit([$1], [-a-z], [_A-Z]), [$2], [$3])
|
||||
])
|
||||
|
||||
AC_DEFUN([CS_STR_WITH], [AC_ARG_WITH([$1],
|
||||
[AS_HELP_STRING(--with-[$1], [default $2 [$3]])],
|
||||
[CS_DEFINE([$1], ["$withval"], [$2])],
|
||||
[CS_DEFINE([$1], ["$3"], [$2])]
|
||||
)])
|
||||
|
||||
AC_DEFUN([CS_NUM_WITH], [AC_ARG_WITH([$1],
|
||||
[AS_HELP_STRING(--with-[$1], [default $2 [$3]])],
|
||||
[CS_DEFINE([$1], [$withval], [$2])],
|
||||
[CS_DEFINE([$1], [$3], [$2])]
|
||||
)])
|
||||
|
||||
dnl ==========================================================================
|
||||
dnl Python bindings
|
||||
AC_ARG_ENABLE([python], AS_HELP_STRING([--enable-python],[enable Python bindings]),
|
||||
[with_python=$enableval],
|
||||
[with_python=no])
|
||||
|
||||
if test "x$with_python" = "xyes"; then
|
||||
AM_PATH_PYTHON([2.4])
|
||||
|
||||
if ! test -x "$PYTHON-config" ; then
|
||||
AC_MSG_ERROR([Cannot find python development packages to build bindings])
|
||||
fi
|
||||
|
||||
PYTHON_INCLUDES=$($PYTHON-config --includes)
|
||||
AC_SUBST(PYTHON_INCLUDES)
|
||||
fi
|
||||
AM_CONDITIONAL([PYTHON_CRYPTSETUP], [test "x$with_python" = "xyes"])
|
||||
|
||||
dnl ==========================================================================
|
||||
CS_STR_WITH([plain-hash], [password hashing function for plain mode], [ripemd160])
|
||||
CS_STR_WITH([plain-cipher], [cipher for plain mode], [aes])
|
||||
CS_STR_WITH([plain-mode], [cipher mode for plain mode], [cbc-essiv:sha256])
|
||||
CS_NUM_WITH([plain-keybits],[key length in bits for plain mode], [256])
|
||||
|
||||
CS_STR_WITH([luks1-hash], [hash function for LUKS1 header], [sha1])
|
||||
CS_STR_WITH([luks1-cipher], [cipher for LUKS1], [aes])
|
||||
CS_STR_WITH([luks1-mode], [cipher mode for LUKS1], [cbc-essiv:sha256])
|
||||
CS_NUM_WITH([luks1-keybits],[key length in bits for LUKS1], [256])
|
||||
|
||||
CS_STR_WITH([loopaes-cipher], [cipher for loop-AES mode], [aes])
|
||||
CS_NUM_WITH([loopaes-keybits],[key length in bits for loop-AES mode], [256])
|
||||
|
||||
CS_NUM_WITH([keyfile-size-maxkb],[maximum keyfile size (in KiB)], [8192])
|
||||
CS_NUM_WITH([passphrase-size-max],[maximum keyfile size (in characters)], [512])
|
||||
|
||||
CS_STR_WITH([verity-hash], [hash function for verity mode], [sha256])
|
||||
CS_NUM_WITH([verity-data-block], [data block size for verity mode], [4096])
|
||||
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])
|
||||
|
||||
dnl ==========================================================================
|
||||
|
||||
AM_CONDITIONAL(STATIC_CRYPTSETUP, test x$enable_static = xyes)
|
||||
AM_CONDITIONAL(DYNAMIC_CRYPTSETUP, test x$enable_static = xno)
|
||||
|
||||
dnl ==========================================================================
|
||||
|
||||
AC_OUTPUT([ Makefile
|
||||
AC_CONFIG_FILES([ Makefile
|
||||
lib/Makefile
|
||||
lib/libcryptsetup.pc
|
||||
lib/crypto_backend/Makefile
|
||||
lib/luks1/Makefile
|
||||
lib/loopaes/Makefile
|
||||
lib/verity/Makefile
|
||||
src/Makefile
|
||||
po/Makefile.in
|
||||
luks/Makefile
|
||||
man/Makefile
|
||||
tests/Makefile
|
||||
python/Makefile
|
||||
])
|
||||
AC_OUTPUT
|
||||
|
||||
280
docs/doxyfile
Normal file
280
docs/doxyfile
Normal file
@@ -0,0 +1,280 @@
|
||||
# Doxyfile 1.7.4
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Project related configuration options
|
||||
#---------------------------------------------------------------------------
|
||||
DOXYFILE_ENCODING = UTF-8
|
||||
PROJECT_NAME = "cryptsetup API"
|
||||
PROJECT_NUMBER =
|
||||
PROJECT_BRIEF = "Public cryptsetup API"
|
||||
PROJECT_LOGO =
|
||||
OUTPUT_DIRECTORY = doxygen_api_docs
|
||||
CREATE_SUBDIRS = NO
|
||||
OUTPUT_LANGUAGE = English
|
||||
BRIEF_MEMBER_DESC = YES
|
||||
REPEAT_BRIEF = YES
|
||||
ABBREVIATE_BRIEF =
|
||||
ALWAYS_DETAILED_SEC = NO
|
||||
INLINE_INHERITED_MEMB = NO
|
||||
FULL_PATH_NAMES = YES
|
||||
STRIP_FROM_PATH =
|
||||
STRIP_FROM_INC_PATH =
|
||||
SHORT_NAMES = NO
|
||||
JAVADOC_AUTOBRIEF = NO
|
||||
QT_AUTOBRIEF = NO
|
||||
MULTILINE_CPP_IS_BRIEF = NO
|
||||
INHERIT_DOCS = YES
|
||||
SEPARATE_MEMBER_PAGES = NO
|
||||
TAB_SIZE = 8
|
||||
ALIASES =
|
||||
OPTIMIZE_OUTPUT_FOR_C = YES
|
||||
OPTIMIZE_OUTPUT_JAVA = NO
|
||||
OPTIMIZE_FOR_FORTRAN = NO
|
||||
OPTIMIZE_OUTPUT_VHDL = NO
|
||||
EXTENSION_MAPPING =
|
||||
BUILTIN_STL_SUPPORT = NO
|
||||
CPP_CLI_SUPPORT = NO
|
||||
SIP_SUPPORT = NO
|
||||
IDL_PROPERTY_SUPPORT = YES
|
||||
DISTRIBUTE_GROUP_DOC = NO
|
||||
SUBGROUPING = YES
|
||||
INLINE_GROUPED_CLASSES = NO
|
||||
TYPEDEF_HIDES_STRUCT = YES
|
||||
SYMBOL_CACHE_SIZE = 0
|
||||
#---------------------------------------------------------------------------
|
||||
# Build related configuration options
|
||||
#---------------------------------------------------------------------------
|
||||
EXTRACT_ALL = NO
|
||||
EXTRACT_PRIVATE = NO
|
||||
EXTRACT_STATIC = NO
|
||||
EXTRACT_LOCAL_CLASSES = YES
|
||||
EXTRACT_LOCAL_METHODS = NO
|
||||
EXTRACT_ANON_NSPACES = NO
|
||||
HIDE_UNDOC_MEMBERS = NO
|
||||
HIDE_UNDOC_CLASSES = NO
|
||||
HIDE_FRIEND_COMPOUNDS = NO
|
||||
HIDE_IN_BODY_DOCS = NO
|
||||
INTERNAL_DOCS = NO
|
||||
CASE_SENSE_NAMES = YES
|
||||
HIDE_SCOPE_NAMES = NO
|
||||
SHOW_INCLUDE_FILES = YES
|
||||
FORCE_LOCAL_INCLUDES = NO
|
||||
INLINE_INFO = YES
|
||||
SORT_MEMBER_DOCS = YES
|
||||
SORT_BRIEF_DOCS = NO
|
||||
SORT_MEMBERS_CTORS_1ST = NO
|
||||
SORT_GROUP_NAMES = NO
|
||||
SORT_BY_SCOPE_NAME = NO
|
||||
STRICT_PROTO_MATCHING = NO
|
||||
GENERATE_TODOLIST = YES
|
||||
GENERATE_TESTLIST = YES
|
||||
GENERATE_BUGLIST = YES
|
||||
GENERATE_DEPRECATEDLIST= YES
|
||||
ENABLED_SECTIONS =
|
||||
MAX_INITIALIZER_LINES = 30
|
||||
SHOW_USED_FILES = YES
|
||||
SHOW_DIRECTORIES = NO
|
||||
SHOW_FILES = YES
|
||||
SHOW_NAMESPACES = YES
|
||||
FILE_VERSION_FILTER =
|
||||
LAYOUT_FILE =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to warning and progress messages
|
||||
#---------------------------------------------------------------------------
|
||||
QUIET = NO
|
||||
WARNINGS = YES
|
||||
WARN_IF_UNDOCUMENTED = YES
|
||||
WARN_IF_DOC_ERROR = YES
|
||||
WARN_NO_PARAMDOC = NO
|
||||
WARN_FORMAT = "$file:$line: $text"
|
||||
WARN_LOGFILE =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the input files
|
||||
#---------------------------------------------------------------------------
|
||||
INPUT = "doxygen_index" "../lib/libcryptsetup.h"
|
||||
INPUT_ENCODING = UTF-8
|
||||
FILE_PATTERNS =
|
||||
RECURSIVE = NO
|
||||
EXCLUDE =
|
||||
EXCLUDE_SYMLINKS = NO
|
||||
EXCLUDE_PATTERNS =
|
||||
EXCLUDE_SYMBOLS =
|
||||
EXAMPLE_PATH = "examples"
|
||||
EXAMPLE_PATTERNS =
|
||||
EXAMPLE_RECURSIVE = NO
|
||||
IMAGE_PATH =
|
||||
INPUT_FILTER =
|
||||
FILTER_PATTERNS =
|
||||
FILTER_SOURCE_FILES = NO
|
||||
FILTER_SOURCE_PATTERNS =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to source browsing
|
||||
#---------------------------------------------------------------------------
|
||||
SOURCE_BROWSER = NO
|
||||
INLINE_SOURCES = NO
|
||||
STRIP_CODE_COMMENTS = YES
|
||||
REFERENCED_BY_RELATION = NO
|
||||
REFERENCES_RELATION = NO
|
||||
REFERENCES_LINK_SOURCE = YES
|
||||
USE_HTAGS = NO
|
||||
VERBATIM_HEADERS = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the alphabetical class index
|
||||
#---------------------------------------------------------------------------
|
||||
ALPHABETICAL_INDEX = YES
|
||||
COLS_IN_ALPHA_INDEX = 5
|
||||
IGNORE_PREFIX =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the HTML output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_HTML = YES
|
||||
HTML_OUTPUT = html
|
||||
HTML_FILE_EXTENSION = .html
|
||||
HTML_HEADER =
|
||||
HTML_FOOTER =
|
||||
HTML_STYLESHEET =
|
||||
HTML_EXTRA_FILES =
|
||||
HTML_COLORSTYLE_HUE = 220
|
||||
HTML_COLORSTYLE_SAT = 100
|
||||
HTML_COLORSTYLE_GAMMA = 80
|
||||
HTML_TIMESTAMP = YES
|
||||
HTML_ALIGN_MEMBERS = YES
|
||||
HTML_DYNAMIC_SECTIONS = NO
|
||||
GENERATE_DOCSET = NO
|
||||
DOCSET_FEEDNAME = "Doxygen generated docs"
|
||||
DOCSET_BUNDLE_ID = org.doxygen.Project
|
||||
DOCSET_PUBLISHER_ID = org.doxygen.Publisher
|
||||
DOCSET_PUBLISHER_NAME = Publisher
|
||||
GENERATE_HTMLHELP = NO
|
||||
CHM_FILE =
|
||||
HHC_LOCATION =
|
||||
GENERATE_CHI = NO
|
||||
CHM_INDEX_ENCODING =
|
||||
BINARY_TOC = NO
|
||||
TOC_EXPAND = NO
|
||||
GENERATE_QHP = NO
|
||||
QCH_FILE =
|
||||
QHP_NAMESPACE = org.doxygen.Project
|
||||
QHP_VIRTUAL_FOLDER = doc
|
||||
QHP_CUST_FILTER_NAME =
|
||||
QHP_CUST_FILTER_ATTRS =
|
||||
QHP_SECT_FILTER_ATTRS =
|
||||
QHG_LOCATION =
|
||||
GENERATE_ECLIPSEHELP = NO
|
||||
ECLIPSE_DOC_ID = org.doxygen.Project
|
||||
DISABLE_INDEX = NO
|
||||
ENUM_VALUES_PER_LINE = 4
|
||||
GENERATE_TREEVIEW = NO
|
||||
USE_INLINE_TREES = NO
|
||||
TREEVIEW_WIDTH = 250
|
||||
EXT_LINKS_IN_WINDOW = NO
|
||||
FORMULA_FONTSIZE = 10
|
||||
FORMULA_TRANSPARENT = YES
|
||||
USE_MATHJAX = NO
|
||||
MATHJAX_RELPATH = http://www.mathjax.org/mathjax
|
||||
SEARCHENGINE = YES
|
||||
SERVER_BASED_SEARCH = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the LaTeX output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_LATEX = YES
|
||||
LATEX_OUTPUT = latex
|
||||
LATEX_CMD_NAME = latex
|
||||
MAKEINDEX_CMD_NAME = makeindex
|
||||
COMPACT_LATEX = NO
|
||||
PAPER_TYPE = a4
|
||||
EXTRA_PACKAGES =
|
||||
LATEX_HEADER =
|
||||
LATEX_FOOTER =
|
||||
PDF_HYPERLINKS = YES
|
||||
USE_PDFLATEX = YES
|
||||
LATEX_BATCHMODE = NO
|
||||
LATEX_HIDE_INDICES = NO
|
||||
LATEX_SOURCE_CODE = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the RTF output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_RTF = NO
|
||||
RTF_OUTPUT = rtf
|
||||
COMPACT_RTF = NO
|
||||
RTF_HYPERLINKS = NO
|
||||
RTF_STYLESHEET_FILE =
|
||||
RTF_EXTENSIONS_FILE =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the man page output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_MAN = NO
|
||||
MAN_OUTPUT = man
|
||||
MAN_EXTENSION = .3
|
||||
MAN_LINKS = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the XML output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_XML = NO
|
||||
XML_OUTPUT = xml
|
||||
XML_SCHEMA =
|
||||
XML_DTD =
|
||||
XML_PROGRAMLISTING = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options for the AutoGen Definitions output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_AUTOGEN_DEF = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the Perl module output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_PERLMOD = NO
|
||||
PERLMOD_LATEX = NO
|
||||
PERLMOD_PRETTY = YES
|
||||
PERLMOD_MAKEVAR_PREFIX =
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the preprocessor
|
||||
#---------------------------------------------------------------------------
|
||||
ENABLE_PREPROCESSING = YES
|
||||
MACRO_EXPANSION = NO
|
||||
EXPAND_ONLY_PREDEF = NO
|
||||
SEARCH_INCLUDES = YES
|
||||
INCLUDE_PATH =
|
||||
INCLUDE_FILE_PATTERNS =
|
||||
PREDEFINED =
|
||||
EXPAND_AS_DEFINED =
|
||||
SKIP_FUNCTION_MACROS = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration::additions related to external references
|
||||
#---------------------------------------------------------------------------
|
||||
TAGFILES =
|
||||
GENERATE_TAGFILE =
|
||||
ALLEXTERNALS = NO
|
||||
EXTERNAL_GROUPS = YES
|
||||
PERL_PATH =
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the dot tool
|
||||
#---------------------------------------------------------------------------
|
||||
CLASS_DIAGRAMS = YES
|
||||
MSCGEN_PATH =
|
||||
HIDE_UNDOC_RELATIONS = YES
|
||||
HAVE_DOT = NO
|
||||
DOT_NUM_THREADS = 0
|
||||
DOT_FONTNAME = Helvetica
|
||||
DOT_FONTSIZE = 10
|
||||
DOT_FONTPATH =
|
||||
CLASS_GRAPH = YES
|
||||
COLLABORATION_GRAPH = YES
|
||||
GROUP_GRAPHS = YES
|
||||
UML_LOOK = NO
|
||||
TEMPLATE_RELATIONS = NO
|
||||
INCLUDE_GRAPH = YES
|
||||
INCLUDED_BY_GRAPH = YES
|
||||
CALL_GRAPH = NO
|
||||
CALLER_GRAPH = NO
|
||||
GRAPHICAL_HIERARCHY = YES
|
||||
DIRECTORY_GRAPH = YES
|
||||
DOT_IMAGE_FORMAT = png
|
||||
DOT_PATH =
|
||||
DOTFILE_DIRS =
|
||||
MSCFILE_DIRS =
|
||||
DOT_GRAPH_MAX_NODES = 50
|
||||
MAX_DOT_GRAPH_DEPTH = 0
|
||||
DOT_TRANSPARENT = NO
|
||||
DOT_MULTI_TARGETS = NO
|
||||
GENERATE_LEGEND = YES
|
||||
DOT_CLEANUP = YES
|
||||
125
docs/doxygen_index
Normal file
125
docs/doxygen_index
Normal file
@@ -0,0 +1,125 @@
|
||||
/**
|
||||
* @mainpage Cryptsetup API
|
||||
*
|
||||
* The documentation covers public parts of cryptsetup API. In the following sections you'll find
|
||||
* the examples that describe some features of cryptsetup API.
|
||||
* For more info about libcryptsetup API versions see
|
||||
* <a href="http://upstream-tracker.org/versions/libcryptsetup.html">Upstream Tracker</a>.
|
||||
*
|
||||
* <OL type="A">
|
||||
* <LI>@ref cexamples "Cryptsetup API examples"</LI>
|
||||
* <OL type="1">
|
||||
* <LI>@ref cluks "crypt_luks_usage" - cryptsetup LUKS device type usage examples</LI>
|
||||
* <UL>
|
||||
* <LI>@ref cinit "crypt_init()"</LI>
|
||||
* <LI>@ref cformat "crypt_format()" - header and payload on mutual device</LI>
|
||||
* <LI>@ref ckeys "Keyslot operations" </LI>
|
||||
* <UL>
|
||||
* <LI>@ref ckeyslot_vol "crypt_keyslot_add_by_volume_key()"</LI>
|
||||
* <LI>@ref ckeyslot_pass "crypt_keyslot_add_by_passphrase()"</LI>
|
||||
* </UL>
|
||||
* <LI>@ref cload "crypt_load()"
|
||||
* <LI>@ref cactivate "crypt_activate_by_passphrase()"</LI>
|
||||
* <LI>@ref cactive_pars "crypt_get_active_device()"</LI>
|
||||
* <LI>@ref cinit_by_name "crypt_init_by_name()"</LI>
|
||||
* <LI>@ref cdeactivate "crypt_deactivate()"</LI>
|
||||
* <LI>@ref cluks_ex "crypt_luks_usage.c"</LI>
|
||||
* </UL>
|
||||
* <LI>@ref clog "crypt_log_usage" - cryptsetup logging API examples</LI>
|
||||
* </OL>
|
||||
* </OL>
|
||||
*
|
||||
* @section cexamples Cryptsetup API examples
|
||||
* @section cluks crypt_luks_usage - cryptsetup LUKS device type usage
|
||||
* @subsection cinit crypt_init()
|
||||
*
|
||||
* Every time you need to do something with cryptsetup or dmcrypt device
|
||||
* you need a valid context. The first step to start your work is
|
||||
* @ref crypt_init call. You can call it either with path
|
||||
* to the block device or path to the regular file. If you don't supply the path,
|
||||
* empty context is initialized.
|
||||
*
|
||||
* @subsection cformat crypt_format() - header and payload on mutual device
|
||||
*
|
||||
* This section covers basic use cases for formatting LUKS devices. Format operation
|
||||
* sets device type in context and in case of LUKS header is written at the beginning
|
||||
* of block device. In the example bellow we use the scenario where LUKS header and data
|
||||
* are both stored on the same device. There's also a possibility to store header and
|
||||
* data separately.
|
||||
*
|
||||
* <B>Bear in mind</B> that @ref crypt_format() is destructive operation and it
|
||||
* overwrites part of the backing block device.
|
||||
*
|
||||
* @subsection ckeys Keyslot operations examples
|
||||
*
|
||||
* After successful @ref crypt_format of LUKS device, volume key is not stored
|
||||
* in a persistent way on the device. Keyslot area is an array beyond LUKS header, where
|
||||
* volume key is stored in the encrypted form using user input passphrase. For more info about
|
||||
* LUKS keyslots and how it's actually protected, please look at
|
||||
* <A HREF="http://code.google.com/p/cryptsetup/wiki/Specification">LUKS specification</A>.
|
||||
* There are two basic methods to create a new keyslot:
|
||||
*
|
||||
* @subsection ckeyslot_vol crypt_keyslot_add_by_volume_key()
|
||||
*
|
||||
* Creates a new keyslot directly by encrypting volume_key stored in the device
|
||||
* context. Passphrase should be supplied or user is prompted if passphrase param is
|
||||
* NULL.
|
||||
*
|
||||
* @subsection ckeyslot_pass crypt_keyslot_add_by_passphrase()
|
||||
*
|
||||
* Creates a new keyslot for the volume key by opening existing active keyslot,
|
||||
* extracting volume key from it and storing it into a new keyslot
|
||||
* protected by a new passphrase
|
||||
*
|
||||
* @subsection cload crypt_load()
|
||||
*
|
||||
* Function loads header from backing block device into device context.
|
||||
*
|
||||
* @subsection cactivate crypt_activate_by_passphrase()
|
||||
*
|
||||
* Activates crypt device by user supplied password for keyslot containing the volume_key.
|
||||
* If <I>keyslot</I> parameter is set to <I>CRYPT_ANY_SLOT</I> then all active keyslots
|
||||
* are tried one by one until the volume key is found.
|
||||
*
|
||||
* @subsection cactive_pars crypt_get_active_device()
|
||||
*
|
||||
* This call returns structure containing runtime attributes of active device.
|
||||
*
|
||||
* @subsection cinit_by_name crypt_init_by_name()
|
||||
*
|
||||
* In case you need to do operations with active device (device which already
|
||||
* has its corresponding mapping) and you miss valid device context stored in
|
||||
* *crypt_device reference, you should use this call. Function tries to
|
||||
* get path to backing device from DM, initializes context for it and loads LUKS
|
||||
* header.
|
||||
*
|
||||
* @subsection cdeactivate crypt_deactivate()
|
||||
*
|
||||
* Deactivates crypt device (removes DM mapping and safely erases volume key from kernel).
|
||||
*
|
||||
* @subsection cluks_ex crypt_luks_usage.c - Complex example
|
||||
*
|
||||
* To compile and run use following commands in examples directory:
|
||||
*
|
||||
* @code
|
||||
* make
|
||||
* ./crypt_luks_usage _path_to_[block_device]_file
|
||||
* @endcode
|
||||
*
|
||||
* Note that you need to have the cryptsetup library compiled. @include crypt_luks_usage.c
|
||||
*
|
||||
* @section clog crypt_log_usage - cryptsetup logging API example
|
||||
*
|
||||
* Example describes basic use case for cryptsetup logging. To compile and run
|
||||
* use following commands in examples directory:
|
||||
*
|
||||
* @code
|
||||
* make
|
||||
* ./crypt_log_usage
|
||||
* @endcode
|
||||
*
|
||||
* Note that you need to have the cryptsetup library compiled. @include crypt_log_usage.c
|
||||
*
|
||||
* @example crypt_luks_usage.c
|
||||
* @example crypt_log_usage.c
|
||||
*/
|
||||
17
docs/examples/Makefile
Normal file
17
docs/examples/Makefile
Normal file
@@ -0,0 +1,17 @@
|
||||
TARGETS=crypt_log_usage crypt_luks_usage
|
||||
CFLAGS=-O0 -g -Wall -D_GNU_SOURCE
|
||||
LDLIBS=-lcryptsetup
|
||||
CC=gcc
|
||||
|
||||
all: $(TARGETS)
|
||||
|
||||
crypt_log_usage: crypt_log_usage.o
|
||||
$(CC) -o $@ $^ $(LDLIBS)
|
||||
|
||||
crypt_luks_usage: crypt_luks_usage.o
|
||||
$(CC) -o $@ $^ $(LDLIBS)
|
||||
|
||||
clean:
|
||||
rm -f *.o *~ core $(TARGETS)
|
||||
|
||||
.PHONY: clean
|
||||
96
docs/examples/crypt_log_usage.c
Normal file
96
docs/examples/crypt_log_usage.c
Normal file
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* An example of using logging through libcryptsetup API
|
||||
*
|
||||
* Copyright (C) 2011, 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.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <syslog.h>
|
||||
#include <unistd.h>
|
||||
#include <libcryptsetup.h>
|
||||
|
||||
/*
|
||||
* This is an example of function that can be registered using crypt_set_log_callback API.
|
||||
*
|
||||
* Its prototype is void (*log)(int level, const char *msg, void *usrptr) as defined
|
||||
* in crypt_set_log_callback
|
||||
*/
|
||||
static void simple_syslog_wrapper(int level, const char *msg, void *usrptr)
|
||||
{
|
||||
const char *prefix = (const char *)usrptr;
|
||||
int priority;
|
||||
|
||||
switch(level) {
|
||||
case CRYPT_LOG_NORMAL: priority = LOG_NOTICE; break;
|
||||
case CRYPT_LOG_ERROR: priority = LOG_ERR; break;
|
||||
case CRYPT_LOG_VERBOSE: priority = LOG_INFO; break;
|
||||
case CRYPT_LOG_DEBUG: priority = LOG_DEBUG; break;
|
||||
default:
|
||||
fprintf(stderr, "Unsupported log level requested!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (prefix)
|
||||
syslog(priority, "%s:%s", prefix, msg);
|
||||
else
|
||||
syslog(priority, "%s", msg);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
struct crypt_device *cd;
|
||||
char usrprefix[] = "cslog_example";
|
||||
int r;
|
||||
|
||||
if (geteuid()) {
|
||||
printf("Using of libcryptsetup requires super user privileges.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
openlog("cryptsetup", LOG_CONS | LOG_PID, LOG_USER);
|
||||
|
||||
/* Initialize empty crypt device context */
|
||||
r = crypt_init(&cd, NULL);
|
||||
if (r < 0) {
|
||||
printf("crypt_init() failed.\n");
|
||||
return 2;
|
||||
}
|
||||
|
||||
/* crypt_set_log_callback() - register a log function for crypt context */
|
||||
crypt_set_log_callback(cd, &simple_syslog_wrapper, (void *)usrprefix);
|
||||
|
||||
/* send messages ithrough the crypt_log() interface */
|
||||
crypt_log(cd, CRYPT_LOG_NORMAL, "This is normal log message");
|
||||
crypt_log(cd, CRYPT_LOG_ERROR, "This is error log message");
|
||||
crypt_log(cd, CRYPT_LOG_VERBOSE, "This is verbose log message");
|
||||
crypt_log(cd, CRYPT_LOG_DEBUG, "This is debug message");
|
||||
|
||||
/* release crypt context */
|
||||
crypt_free(cd);
|
||||
|
||||
/* Initialize default (global) log function */
|
||||
crypt_set_log_callback(NULL, &simple_syslog_wrapper, NULL);
|
||||
|
||||
crypt_log(NULL, CRYPT_LOG_NORMAL, "This is normal log message");
|
||||
crypt_log(NULL, CRYPT_LOG_ERROR, "This is error log message");
|
||||
crypt_log(NULL, CRYPT_LOG_VERBOSE, "This is verbose log message");
|
||||
crypt_log(NULL, CRYPT_LOG_DEBUG, "This is debug message");
|
||||
|
||||
closelog();
|
||||
return 0;
|
||||
}
|
||||
294
docs/examples/crypt_luks_usage.c
Normal file
294
docs/examples/crypt_luks_usage.c
Normal file
@@ -0,0 +1,294 @@
|
||||
/*
|
||||
* An example of using LUKS device through libcryptsetup API
|
||||
*
|
||||
* Copyright (C) 2011, 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.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <inttypes.h>
|
||||
#include <sys/types.h>
|
||||
#include <libcryptsetup.h>
|
||||
|
||||
static int format_and_add_keyslots(const char *path)
|
||||
{
|
||||
struct crypt_device *cd;
|
||||
struct crypt_params_luks1 params;
|
||||
int r;
|
||||
|
||||
/*
|
||||
* crypt_init() call precedes most of operations of cryptsetup API. The call is used
|
||||
* to initialize crypt device context stored in structure referenced by _cd_ in
|
||||
* the example. Second parameter is used to pass underlaying device path.
|
||||
*
|
||||
* Note:
|
||||
* If path refers to a regular file it'll be attached to a first free loop device.
|
||||
* crypt_init() operation fails in case there's no more loop device available.
|
||||
* Also, loop device will have the AUTOCLEAR flag set, so the file loopback will
|
||||
* be detached automatically.
|
||||
*/
|
||||
|
||||
r = crypt_init(&cd, path);
|
||||
if (r < 0 ) {
|
||||
printf("crypt_init() failed for %s.\n", path);
|
||||
return r;
|
||||
}
|
||||
|
||||
printf("Context is attached to block device %s.\n", crypt_get_device_name(cd));
|
||||
|
||||
/*
|
||||
* So far no data were written on your device. This will change with call of
|
||||
* crypt_format() only if you specify CRYPT_LUKS1 as device type.
|
||||
*/
|
||||
printf("Device %s will be formatted to LUKS device after 5 seconds.\n"
|
||||
"Press CTRL+C now if you want to cancel this operation.\n", path);
|
||||
sleep(5);
|
||||
|
||||
|
||||
/*
|
||||
* Prepare LUKS format parameters
|
||||
*
|
||||
* hash parameter defines PBKDF2 hash algorithm used in LUKS header.
|
||||
* For compatibility reason we use SHA1 here.
|
||||
*/
|
||||
params.hash = "sha1";
|
||||
|
||||
/*
|
||||
* data_alignment parameter is relevant only in case of the luks header
|
||||
* and the payload are both stored on same device.
|
||||
*
|
||||
* if you set data_alignment = 0, cryptsetup will autodetect
|
||||
* data_alignment according to underlaying device topology.
|
||||
*/
|
||||
params.data_alignment = 0;
|
||||
|
||||
/*
|
||||
* data_device parameter defines that no external device
|
||||
* for luks header will be used
|
||||
*/
|
||||
params.data_device = NULL;
|
||||
|
||||
/*
|
||||
* NULLs for uuid and volume_key means that these attributes will be
|
||||
* generated during crypt_format(). Volume key is generated with respect
|
||||
* to key size parameter passed to function.
|
||||
*
|
||||
* crypt_format() checks device size (LUKS header must fit there).
|
||||
*/
|
||||
r = crypt_format(cd, /* crypt context */
|
||||
CRYPT_LUKS1, /* LUKS1 is standard LUKS header */
|
||||
"aes", /* used cipher */
|
||||
"xts-plain64", /* used block mode and IV generator*/
|
||||
NULL, /* generate UUID */
|
||||
NULL, /* generate volume key from RNG */
|
||||
256 / 8, /* 256bit key - here AES-128 in XTS mode, size is in bytes */
|
||||
¶ms); /* parameters above */
|
||||
|
||||
if(r < 0) {
|
||||
printf("crypt_format() failed on device %s\n", crypt_get_device_name(cd));
|
||||
crypt_free(cd);
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* The device now contains LUKS1 header, but there is
|
||||
* no active keyslot with encrypted volume key yet.
|
||||
*/
|
||||
|
||||
/*
|
||||
* cryptt_kesylot_add_* call stores volume_key in encrypted form into keyslot.
|
||||
* Without keyslot you can't manipulate with LUKS device after the context will be freed.
|
||||
*
|
||||
* To create a new keyslot you need to supply the existing one (to get the volume key from) or
|
||||
* you need to supply the volume key.
|
||||
*
|
||||
* After format, we have volume key stored internally in context so add new keyslot
|
||||
* using this internal volume key.
|
||||
*/
|
||||
r = crypt_keyslot_add_by_volume_key(cd, /* crypt context */
|
||||
CRYPT_ANY_SLOT, /* just use first free slot */
|
||||
NULL, /* use internal volume key */
|
||||
0, /* unused (size of volume key) */
|
||||
"foo", /* passphrase - NULL means query*/
|
||||
3); /* size of passphrase */
|
||||
|
||||
if (r < 0) {
|
||||
printf("Adding keyslot failed.\n");
|
||||
crypt_free(cd);
|
||||
return r;
|
||||
}
|
||||
|
||||
printf("The first keyslot is initialized.\n");
|
||||
|
||||
/*
|
||||
* Add another keyslot, now using the first keyslot.
|
||||
* It will decrypt volume key from the first keyslot and creates new one with another passphrase.
|
||||
*/
|
||||
r = crypt_keyslot_add_by_passphrase(cd, /* crypt context */
|
||||
CRYPT_ANY_SLOT, /* just use first free slot */
|
||||
"foo", 3, /* passphrase for the old keyslot */
|
||||
"bar", 3); /* passphrase for the new kesylot */
|
||||
if (r < 0) {
|
||||
printf("Adding keyslot failed.\n");
|
||||
crypt_free(cd);
|
||||
return r;
|
||||
}
|
||||
|
||||
printf("The second keyslot is initialized.\n");
|
||||
|
||||
crypt_free(cd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int activate_and_check_status(const char *path, const char *device_name)
|
||||
{
|
||||
struct crypt_device *cd;
|
||||
struct crypt_active_device cad;
|
||||
int r;
|
||||
|
||||
/*
|
||||
* LUKS device activation example.
|
||||
* It's sequence of sub-steps: device initialization, LUKS header load
|
||||
* and the device activation itself.
|
||||
*/
|
||||
r = crypt_init(&cd, path);
|
||||
if (r < 0 ) {
|
||||
printf("crypt_init() failed for %s.\n", path);
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* crypt_load() is used to load the LUKS header from block device
|
||||
* into crypt_device context.
|
||||
*/
|
||||
r = crypt_load(cd, /* crypt context */
|
||||
CRYPT_LUKS1, /* requested type */
|
||||
NULL); /* additional parameters (not used) */
|
||||
|
||||
if (r < 0) {
|
||||
printf("crypt_load() failed on device %s.\n", crypt_get_device_name(cd));
|
||||
crypt_free(cd);
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* Device activation creates device-mapper devie mapping with name device_name.
|
||||
*/
|
||||
r = crypt_activate_by_passphrase(cd, /* crypt context */
|
||||
device_name, /* device name to activate */
|
||||
CRYPT_ANY_SLOT,/* which slot use (ANY - try all) */
|
||||
"foo", 3, /* passphrase */
|
||||
CRYPT_ACTIVATE_READONLY); /* flags */
|
||||
if (r < 0) {
|
||||
printf("Device %s activation failed.\n", device_name);
|
||||
crypt_free(cd);
|
||||
return r;
|
||||
}
|
||||
|
||||
printf("LUKS device %s/%s is active.\n", crypt_get_dir(), device_name);
|
||||
printf("\tcipher used: %s\n", crypt_get_cipher(cd));
|
||||
printf("\tcipher mode: %s\n", crypt_get_cipher_mode(cd));
|
||||
printf("\tdevice UUID: %s\n", crypt_get_uuid(cd));
|
||||
|
||||
/*
|
||||
* Get info about active device (query DM backend)
|
||||
*/
|
||||
r = crypt_get_active_device(cd, device_name, &cad);
|
||||
if (r < 0) {
|
||||
printf("Get info about active device %s failed.\n", device_name);
|
||||
crypt_deactivate(cd, device_name);
|
||||
crypt_free(cd);
|
||||
return r;
|
||||
}
|
||||
|
||||
printf("Active device parameters for %s:\n"
|
||||
"\tDevice offset (in sectors): %" PRIu64 "\n"
|
||||
"\tIV offset (in sectors) : %" PRIu64 "\n"
|
||||
"\tdevice size (in sectors) : %" PRIu64 "\n"
|
||||
"\tread-only flag : %s\n",
|
||||
device_name, cad.offset, cad.iv_offset, cad.size,
|
||||
cad.flags & CRYPT_ACTIVATE_READONLY ? "1" : "0");
|
||||
|
||||
crypt_free(cd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int handle_active_device(const char *device_name)
|
||||
{
|
||||
struct crypt_device *cd;
|
||||
int r;
|
||||
|
||||
/*
|
||||
* crypt_init_by_name() initializes device context and loads LUKS header from backing device
|
||||
*/
|
||||
r = crypt_init_by_name(&cd, device_name);
|
||||
if (r < 0) {
|
||||
printf("crypt_init_by_name() failed for %s.\n", device_name);
|
||||
return r;
|
||||
}
|
||||
|
||||
if (crypt_status(cd, device_name) == CRYPT_ACTIVE)
|
||||
printf("Device %s is still active.\n", device_name);
|
||||
else {
|
||||
printf("Something failed perhaps, device %s is not active.\n", device_name);
|
||||
crypt_free(cd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* crypt_deactivate() is used to deactivate device
|
||||
*/
|
||||
r = crypt_deactivate(cd, device_name);
|
||||
if (r < 0) {
|
||||
printf("crypt_deactivate() failed.\n");
|
||||
crypt_free(cd);
|
||||
return r;
|
||||
}
|
||||
|
||||
printf("Device %s is now deactivated.\n", device_name);
|
||||
|
||||
crypt_free(cd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
if (geteuid()) {
|
||||
printf("Using of libcryptsetup requires super user privileges.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (argc != 2) {
|
||||
printf("usage: ./crypt_luks_usage <path>\n"
|
||||
"<path> refers to either a regular file or a block device.\n"
|
||||
" WARNING: the file or device will be wiped.\n");
|
||||
return 2;
|
||||
}
|
||||
|
||||
if (format_and_add_keyslots(argv[1]))
|
||||
return 3;
|
||||
|
||||
if (activate_and_check_status(argv[1], "example_device"))
|
||||
return 4;
|
||||
|
||||
if (handle_active_device("example_device"))
|
||||
return 5;
|
||||
|
||||
return 0;
|
||||
}
|
||||
BIN
docs/on-disk-format.pdf
Normal file
BIN
docs/on-disk-format.pdf
Normal file
Binary file not shown.
92
docs/v1.0.7-ReleaseNotes
Normal file
92
docs/v1.0.7-ReleaseNotes
Normal file
@@ -0,0 +1,92 @@
|
||||
cryptsetup 1.0.7 Release Notes (2009-07-22)
|
||||
===========================================
|
||||
|
||||
Changes since 1.0.7-rc1
|
||||
------------------------
|
||||
[committer name]
|
||||
|
||||
* Allow removal of last slot in luksRemoveKey
|
||||
and luksKillSlot. [Milan Broz]
|
||||
|
||||
* Add --disable-selinux option and fix static build if selinux
|
||||
is required. [Milan Broz]
|
||||
|
||||
* Reject unsupported --offset and --skip options for luksFormat
|
||||
and update man page. [Milan Broz]
|
||||
|
||||
|
||||
Changes since 1.0.6
|
||||
--------------------
|
||||
[committer name]
|
||||
|
||||
* Various man page fixes. Also merged some Debian/Ubuntu man page
|
||||
fixes. (thanks to Martin Pitt) [Milan Broz]
|
||||
|
||||
* Set UUID in device-mapper for LUKS devices. [Milan Broz]
|
||||
|
||||
* Retain readahead of underlying device. [Milan Broz]
|
||||
|
||||
* Display device name when asking for password. (thanks to Till
|
||||
Maas) [Milan Broz]
|
||||
|
||||
* Check device size when loading LUKS header. Remove misleading
|
||||
error message later. [Milan Broz]
|
||||
|
||||
* Add error hint if dm-crypt mapping failed. (Key size and kernel
|
||||
version check for XTS and LRW mode for now.) [Milan Broz]
|
||||
|
||||
* Use better error messages if device doesn't exist or is already
|
||||
used by other mapping. [Milan Broz]
|
||||
|
||||
* Fix make distcheck. (thanks to Mike Kelly) [Milan Broz]
|
||||
|
||||
* Check if all slots are full during luksAddKey. [Clemens Fruhwirth]
|
||||
|
||||
* Fix segfault in set_error (thanks to Oliver Metz). [Clemens Fruhwirth]
|
||||
|
||||
* Remove precompiled pot files. Fix uninitialized return value
|
||||
variable in setup.c. [Clemens Fruhwirth]
|
||||
|
||||
* Code cleanups. (thanks to Ivan Stankovic) [Clemens Fruhwirth]
|
||||
|
||||
* Remove unnecessary files from po directory. They will be
|
||||
regenerated by autogen.sh. [Clemens Fruhwirth]
|
||||
|
||||
* Fix wrong output for remaining key at key deletion. Allow deletion
|
||||
of key slot while other keys have the same key information. [Clemens
|
||||
Fruhwirth]
|
||||
|
||||
* Add missing AM_PROG_CC_C_O to configure.in [Milan Broz]
|
||||
|
||||
* Remove duplicate sentence in man page (thanks to Till Maas).
|
||||
[Milan Broz]
|
||||
|
||||
* Wipe start of device (possible fs signature) before
|
||||
LUKS-formatting. [Milan Broz]
|
||||
|
||||
* Do not process configure.in in hidden directories. [Milan Broz]
|
||||
|
||||
* Return more descriptive error in case of IO or header format
|
||||
error. [Milan Broz]
|
||||
|
||||
* Use remapping to error target instead of calling udevsettle
|
||||
for temporary crypt device. [Milan Broz]
|
||||
|
||||
* Check device mapper communication and warn user in case the
|
||||
communication fails. (thanks to Milan Broz) [Clemens Fruhwirth]
|
||||
|
||||
* Fix signal handler to proper close device. (thanks to Milan Broz)
|
||||
[Clemens Fruhwirth]
|
||||
|
||||
* write_lseek_blockwise: declare innerCount outside the if block,
|
||||
add -Wall to the default CFLAGS, * fix some signedness issues
|
||||
(thanks to Ivan Stankovic) [Clemens Fruhwirth]
|
||||
|
||||
* Error handling improvement. (thanks to Erik Edin) [Clemens Fruhwirth]
|
||||
|
||||
* Add non-exclusive override to interface definition. [Clemens
|
||||
Fruhwirth]
|
||||
|
||||
* Refactor key slot selection into keyslot_from_option. Either
|
||||
autoselect next free keyslot or honor user choice (after checking).
|
||||
[Clemens Fruhwirth]
|
||||
110
docs/v1.1.0-ReleaseNotes
Normal file
110
docs/v1.1.0-ReleaseNotes
Normal file
@@ -0,0 +1,110 @@
|
||||
Cryptsetup 1.1.0 Release Notes
|
||||
==============================
|
||||
|
||||
Changes since version 1.0.7
|
||||
----------------------------
|
||||
|
||||
Important changes:
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* IMPORTANT: the default compiled-in cipher parameters changed
|
||||
plain mode: aes-cbc-essiv:sha256 (default is backward incompatible!).
|
||||
LUKS mode: aes-cbc-essiv:sha256 (only key size increased)
|
||||
In both modes is now default key size 256bits.
|
||||
|
||||
* Default compiled-in parameters are now configurable through configure options:
|
||||
--with-plain-* / --with-luks1-* (see configure --help)
|
||||
|
||||
* If you need backward compatible defaults for distribution use
|
||||
configure --with-plain-mode=cbc-plain --with-luks1-keybits=128
|
||||
|
||||
Default compiled-in modes are printed in "cryptsetup --help" output.
|
||||
|
||||
* Change in iterations count (LUKS):
|
||||
The slot and key digest iteration minimum count is now 1000.
|
||||
The key digest iteration count is calculated from iteration time (approx 1/8 of req. time).
|
||||
For more info about above items see discussion here: http://tinyurl.com/yaug97y
|
||||
|
||||
* New libcryptsetup API (documented in libcryptsetup.h).
|
||||
|
||||
The old API (using crypt_options struct) is still available but will remain
|
||||
frozen and not used for new functions.
|
||||
Soname of library changed to libcryptsetup.so.1.0.0.
|
||||
(But only recompilation should be needed for old programs.)
|
||||
|
||||
The new API provides much more flexible operation over LUKS device for
|
||||
applications, it is preferred that new applications will use libcryptsetup
|
||||
and not wrapper around cryptsetup binary.
|
||||
|
||||
* New luksHeaderBackup and luksHeaderRestore commands.
|
||||
|
||||
These commands allows binary backup of LUKS header.
|
||||
Please read man page about possible security issues with backup files.
|
||||
|
||||
* New luksSuspend (freeze device and wipe key) and luksResume (with provided passphrase).
|
||||
|
||||
luksSuspend wipe encryption key in kernel memory and set device to suspend
|
||||
(blocking all IO) state. This option can be used for situations when you need
|
||||
temporary wipe encryption key (like suspend to RAM etc.)
|
||||
Please read man page for more information.
|
||||
|
||||
* New --master-key-file option for luksFormat and luksAddKey.
|
||||
|
||||
User can now specify pre-generated master key in file, which allows regenerating
|
||||
LUKS header or add key with only master key knowledge.
|
||||
|
||||
* Uses libgcrypt and enables all gcrypt hash algorithms for LUKS through -h luksFormat option.
|
||||
|
||||
Please note that using different hash for LUKS header make device incompatible with
|
||||
old cryptsetup releases.
|
||||
|
||||
* Introduces --debug parameter.
|
||||
|
||||
Use when reporting bugs (just run cryptsetup with --debug and attach output
|
||||
to issue report.) Sensitive data are never printed to this log.
|
||||
|
||||
* Moves command successful messages to verbose level.
|
||||
|
||||
* Requires device-mapper library and libgcrypt to build.
|
||||
|
||||
* Uses dm-uuid for all crypt devices, contains device type and name now.
|
||||
|
||||
* Removes support for dangerous non-exclusive option
|
||||
(it is ignored now, LUKS device must be always opened exclusive)
|
||||
|
||||
Other changes:
|
||||
~~~~~~~~~~~~~~
|
||||
* Fixed localization to work again. Also cryptsetup is now translated by translationproject.org.
|
||||
* Fix some libcryptsetup problems, including
|
||||
* exported symbols and versions in libcryptsetup (properly use versioned symbols)
|
||||
* Add crypt_log library function.
|
||||
* Add CRYPT_ prefix to enum defined in libcryptsetup.h.
|
||||
* Move duplicate Command failed message to verbose level (error is printed always).
|
||||
* Fix several problems in build system
|
||||
* use autopoint and clean gettext processing.
|
||||
* Check in configure if selinux libraries are required in static version.
|
||||
* Fix build for non-standard location of gcrypt library.
|
||||
* Add temporary debug code to find processes locking internal device.
|
||||
* Fix error handling during reading passphrase.
|
||||
* Fail passphrase read if piped input no longer exists.
|
||||
* Fix man page to not require --size which expands to device size by default.
|
||||
* Clean up Makefiles and configure script.
|
||||
* Try to read first sector from device to properly check that device is ready.
|
||||
* Move memory locking and dm initialization to command layer.
|
||||
* Increase priority of process if memory is locked.
|
||||
* Add log macros and make logging more consistent.
|
||||
* Keyfile now must be provided by path, only stdin file descriptor is used (api only).
|
||||
* Do not call isatty() on closed keyfile descriptor.
|
||||
* Move key slot manipulation function into LUKS specific code.
|
||||
* Replace global options struct with separate parameters in helper functions.
|
||||
* Implement old API calls using new functions.
|
||||
* Allow using passphrase provided in options struct for LuksOpen.
|
||||
* Allow restrict keys size in LuksOpen.
|
||||
* Fix errors when compiled with LUKS_DEBUG.
|
||||
* Print error when getline fails.
|
||||
* Completely remove internal SHA1 implementation code, not needed anymore.
|
||||
* Pad luks header to 512 sector size.
|
||||
* Rework read/write blockwise to not split operation to many pieces.
|
||||
* Use posix_memalign if available.
|
||||
* Fix segfault if provided slot in luksKillslot is invalid.
|
||||
* Remove unneeded timeout when remove of temporary device succeeded.
|
||||
47
docs/v1.1.1-ReleaseNotes
Normal file
47
docs/v1.1.1-ReleaseNotes
Normal file
@@ -0,0 +1,47 @@
|
||||
Cryptsetup 1.1.1 Release Notes
|
||||
==============================
|
||||
|
||||
Changes since version 1.1.1-rc2
|
||||
* Fix luksClose error if underlying device is LVM logical volume.
|
||||
|
||||
Changes since version 1.1.1-rc1
|
||||
* Fix automatic dm-crypt module loading.
|
||||
|
||||
Changes since version 1.1.0
|
||||
|
||||
Important changes:
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* Detects and use device-mapper udev support if available.
|
||||
|
||||
This should allow synchronisation with udev rules and avoid races with udev.
|
||||
|
||||
If package maintainer want to use old, direct libdevmapper device node creation,
|
||||
use configure option --disable-udev.
|
||||
|
||||
* Supports device topology detection for data alignment.
|
||||
|
||||
If kernel provides device topology ioctl calls, the LUKS data area
|
||||
alignment is automatically set to optimal value.
|
||||
|
||||
This means that stacked devices (like LUKS over MD/LVM)
|
||||
should use the most optimal data alignment.
|
||||
|
||||
(You can still overwrite this calculation using --align-payload option.)
|
||||
|
||||
* Prefers some device paths in status display.
|
||||
(So status command will try to find top level device name, like /dev/sdb.)
|
||||
|
||||
* Fix package config file to use proper package version.
|
||||
|
||||
Other changes:
|
||||
~~~~~~~~~~~~~~
|
||||
* Fix luksOpen reading of passphrase on stdin (if "-" keyfile specified).
|
||||
* Fix isLuks to initialise crypto backend (blkid instead is suggested anyway).
|
||||
* Properly initialise crypto backend in header backup/restore commands.
|
||||
* Do not verify unlocking passphrase in luksAddKey command.
|
||||
* Allow no hash specification in plain device constructor - user can provide volume key directly.
|
||||
* Try to use pkgconfig for device mapper library in configuration script.
|
||||
* Add some compatibility checks and disable LUKS suspend/resume if not supported.
|
||||
* Rearrange tests, "make check" now run all available test for package.
|
||||
* Avoid class C++ keyword in library header.
|
||||
33
docs/v1.1.2-ReleaseNotes
Normal file
33
docs/v1.1.2-ReleaseNotes
Normal file
@@ -0,0 +1,33 @@
|
||||
== Cryptsetup 1.1.2 Release Notes ==
|
||||
|
||||
This release fixes a regression (introduced in 1.1.1 version) in handling
|
||||
key files containing new line characters (affects only files read from
|
||||
standard input).
|
||||
|
||||
Cryptsetup can accept passphrase on stdin (standard input).
|
||||
|
||||
Handling of new line (\n) character is defined by input specification:
|
||||
|
||||
* if keyfile is specified as "-" (using --key-file=- of by "-" positional argument
|
||||
in luksFormat and luksAddKey, like cat file | cryptsetup --key-file=- <action>),
|
||||
input is processed as normal binary file and no new line is interpreted.
|
||||
|
||||
* if there is no key file specification (with default input from stdin pipe
|
||||
like echo passphrase | cryptsetup <action>) input is processed as input from terminal,
|
||||
reading will stop after new line is detected.
|
||||
|
||||
Moreover, luksFormat now understands --key-file (in addition to positional key
|
||||
file argument).
|
||||
|
||||
N.B. Using of standard input and pipes for passphrases should be avoided if possible,
|
||||
cryptsetup have no control of used pipe buffers between commands in scripts and cannot
|
||||
guarantee that all passphrase/key-file buffers are properly wiped after use.
|
||||
|
||||
=== changes since version 1.1.1 ===
|
||||
|
||||
* Fix luksFormat/luksOpen reading passphrase from stdin and "-" keyfile.
|
||||
* Support --key-file/-d option for luksFormat.
|
||||
* Fix description of --key-file and add --verbose and --debug options to man page.
|
||||
* Add verbose log level and move unlocking message there.
|
||||
* Remove device even if underlying device disappeared (remove, luksClose).
|
||||
* Fix (deprecated) reload device command to accept new device argument.
|
||||
13
docs/v1.1.3-ReleaseNotes
Normal file
13
docs/v1.1.3-ReleaseNotes
Normal file
@@ -0,0 +1,13 @@
|
||||
== Cryptsetup 1.1.3 Release Notes ==
|
||||
|
||||
=== changes since version 1.1.2 ===
|
||||
|
||||
* Fix device alignment ioctl calls parameters.
|
||||
(Device alignment code was not working properly on some architectures like ppc64.)
|
||||
|
||||
* Fix activate_by_* API calls to handle NULL device name as documented.
|
||||
(To enable check of passphrase/keyfile using libcryptsetup without activating the device.)
|
||||
|
||||
* Fix udev support for old libdevmapper with not compatible definition.
|
||||
|
||||
* Added Polish translation file.
|
||||
126
docs/v1.2.0-ReleaseNotes
Normal file
126
docs/v1.2.0-ReleaseNotes
Normal file
@@ -0,0 +1,126 @@
|
||||
Cryptsetup 1.2.0 Release Notes
|
||||
==============================
|
||||
|
||||
Changes since version 1.2.0-rc1
|
||||
|
||||
* Fix crypt_activate_by_keyfile() to work with PLAIN devices.
|
||||
* Fix plain create command to properly handle keyfile size.
|
||||
* Update translations.
|
||||
|
||||
Changes since version 1.1.3
|
||||
|
||||
Important changes
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
* Add text version of *FAQ* (Frequently Asked Questions) to distribution.
|
||||
|
||||
* Add selection of random/urandom number generator for luksFormat
|
||||
(option --use-random and --use-urandom).
|
||||
|
||||
(This affects only long term volume key in *luksFormat*,
|
||||
not RNG used for salt and AF splitter).
|
||||
|
||||
You can also set the default to /dev/random during compilation with
|
||||
--enable-dev-random. Compiled-in default is printed in --help output.
|
||||
|
||||
Be very careful before changing default to blocking /dev/random use here.
|
||||
|
||||
* Fix *luksRemoveKey* to not ask for remaining keyslot passphrase,
|
||||
only for removed one.
|
||||
|
||||
* No longer support *luksDelKey* (replaced with luksKillSlot).
|
||||
* if you want to remove particular passphrase, use *luksKeyRemove*
|
||||
* if you want to remove particular keyslot, use *luksKillSlot*
|
||||
|
||||
Note that in batch mode *luksKillSlot* allows removing of any keyslot
|
||||
without question, in normal mode requires passphrase or keyfile from
|
||||
other keyslot.
|
||||
|
||||
* *Default alignment* for device (if not overridden by topology info)
|
||||
is now (multiple of) *1MiB*.
|
||||
This reflects trends in storage technologies and aligns to the same
|
||||
defaults for partitions and volume management.
|
||||
|
||||
* Allow explicit UUID setting in *luksFormat* and allow change it later
|
||||
in *luksUUID* (--uuid parameter).
|
||||
|
||||
* All commands using key file now allows limited read from keyfile using
|
||||
--keyfile-size and --new-keyfile-size parameters (in bytes).
|
||||
|
||||
This change also disallows overloading of --key-size parameter which
|
||||
is now exclusively used for key size specification (in bits.)
|
||||
|
||||
* *luksFormat* using pre-generated master key now properly allows
|
||||
using key file (only passphrase was allowed prior to this update).
|
||||
|
||||
* Add --dump-master-key option for *luksDump* to perform volume (master)
|
||||
key dump. Note that printed information allows accessing device without
|
||||
passphrase so it must be stored encrypted.
|
||||
|
||||
This operation is useful for simple Key Escrow function (volume key and
|
||||
encryption parameters printed on paper on safe place).
|
||||
|
||||
This operation requires passphrase or key file.
|
||||
|
||||
* The reload command is no longer supported.
|
||||
(Use dmsetup reload instead if needed. There is no real use for this
|
||||
function except explicit data corruption:-)
|
||||
|
||||
* Cryptsetup now properly checks if underlying device is in use and
|
||||
disallows *luksFormat*, *luksOpen* and *create* commands on open
|
||||
(e.g. already mapped or mounted) device.
|
||||
|
||||
* Option --non-exclusive (already deprecated) is removed.
|
||||
|
||||
Libcryptsetup API additions:
|
||||
|
||||
* new functions
|
||||
* crypt_get_type() - explicit query to crypt device context type
|
||||
* crypt_resize() - new resize command using context
|
||||
* crypt_keyslot_max() - helper to get number of supported keyslots
|
||||
* crypt_get_active_device() - get active device info
|
||||
* crypt_set/get_rng_type() - random/urandom RNG setting
|
||||
* crypt_set_uuid() - explicit UUID change of existing device
|
||||
* crypt_get_device_name() - get underlying device name
|
||||
|
||||
* Fix optional password callback handling.
|
||||
|
||||
* Allow to activate by internally cached volume key immediately after
|
||||
crypt_format() without active slot (for temporary devices with
|
||||
on-disk metadata)
|
||||
|
||||
* libcryptsetup is binary compatible with 1.1.x release and still
|
||||
supports legacy API calls
|
||||
|
||||
* cryptsetup binary now uses only new API calls.
|
||||
|
||||
* Static compilation of both library (--enable-static) and cryptsetup
|
||||
binary (--enable-static-cryptsetup) is now properly implemented by common
|
||||
libtool logic.
|
||||
|
||||
Prior to this it produced miscompiled dynamic cryptsetup binary with
|
||||
statically linked libcryptsetup.
|
||||
|
||||
The static binary is compiled as src/cryptsetup.static in parallel
|
||||
with dynamic build if requested.
|
||||
|
||||
Other changes
|
||||
~~~~~~~~~~~~~
|
||||
* Fix default plain password entry from terminal in activate_by_passphrase.
|
||||
* Initialize volume key from active device in crypt_init_by_name()
|
||||
* Fix cryptsetup binary exit codes.
|
||||
0 - success, otherwise fail
|
||||
1 - wrong parameters
|
||||
2 - no permission
|
||||
3 - out of memory
|
||||
4 - wrong device specified
|
||||
5 - device already exists or device is busy
|
||||
* Remove some obsolete info from man page.
|
||||
* Add more regression tests for commands.
|
||||
* Fix possible double free when handling master key file.
|
||||
* Fix pkg-config use in automake scripts.
|
||||
* Wipe iteration and salt after luksKillSlot in LUKS header.
|
||||
* Rewrite file differ test to C (and fix it to really work).
|
||||
* Do not query non-existent device twice (cryptsetup status /dev/nonexistent).
|
||||
* Check if requested hash is supported before writing LUKS header.
|
||||
* Fix problems reported by clang scan-build.
|
||||
101
docs/v1.3.0-ReleaseNotes
Normal file
101
docs/v1.3.0-ReleaseNotes
Normal file
@@ -0,0 +1,101 @@
|
||||
Cryptsetup 1.3.0 Release Notes
|
||||
==============================
|
||||
|
||||
Changes since version 1.2.0
|
||||
|
||||
Important changes
|
||||
~~~~~~~~~~~~~~~~~
|
||||
* Several userspace crypto backends support
|
||||
|
||||
cryptsetup now supports generic crypto backend interface which allows
|
||||
compile package with various crypto libraries, these are already implemented:
|
||||
|
||||
* gcrypt (default, used in previous versions)
|
||||
* OpenSSL
|
||||
* NSS (because of missing ripemd160 it cannot provide full backward compatibility)
|
||||
* kernel userspace API (provided by kernel 2.6.38 and above)
|
||||
(Note that kernel userspace backend is very slow for this type of operation.
|
||||
But it can be usefull for embedded systems, because you can avoid userspace
|
||||
crypto library completely.)
|
||||
|
||||
Backend is selected during configure time, using --with-crypto_backend option.
|
||||
|
||||
configure --with-crypto_backend=BACKEND (gcrypt/openssl/nss/kernel) [gcrypt]
|
||||
|
||||
Note that performance checked (iterations) in LUKS header will cause that
|
||||
real iteration time will differ with different backends.
|
||||
(There are huge differences in speed between libraries.)
|
||||
|
||||
* Cryptsetup now automatically allocates loopback device (/dev/loop) if device
|
||||
argument is file and not plain device.
|
||||
|
||||
This require Linux kernel 2.6.25 and above (which implements loop autoclear flag).
|
||||
|
||||
You can see backing file in cryptsetup status output if underlying device is loopback.
|
||||
|
||||
* Introduce maximum default keyfile size, add configure option, visible in --help.
|
||||
|
||||
Cryptsetup now fails if read from keyfile exceeds internal limit.
|
||||
You can always specify keyfile size (overrides limit) by using --keyfile-size option.
|
||||
|
||||
* Adds luksChangeKey command
|
||||
|
||||
cryptestup luksChangeKey --key-file <old keyfile> <new keyfile> [--key-slot X]
|
||||
cryptestup luksChangeKey [--key-slot X] (for passphrase change)
|
||||
|
||||
This command allows passphrase/keyfile change in one step. If no key slot is
|
||||
specified (and there is still free key slot on device) new slot is allocated before
|
||||
the old is purged.
|
||||
|
||||
If --key-slot option is specified (or there is no free slot) command will overwrite
|
||||
existing slot.
|
||||
WARNING: Be sure you have another slot active or header backup when using explicit
|
||||
key slot (so you can unlock the device even after possible media failure).
|
||||
|
||||
* Adds compatible support for loop-AES encryption type in loopaesOpen command.
|
||||
|
||||
Linux dm-crypt in 2.6.38 and above supports loop-AES compatible mapping
|
||||
(including multi-key and special CBC mode, all three modes are supported).
|
||||
|
||||
If you have raw loop-AES keyfile (text file with uuencoded per-line keys), you can
|
||||
access loop-AES volume using
|
||||
cryptsetup loopaesOpen <device> <name> [--key-size 128] --key-file <key-file>
|
||||
|
||||
If you are using GPG encrypted keyfile
|
||||
gpg --decrypt <key-file> | cryptsetup loopaesOpen --key-file=- <device> <name>
|
||||
|
||||
Do not forget to specify key size. Version and hash is automatically detected
|
||||
according to number of lines in key file. For special configuration you can
|
||||
override IV sector offset using --skip option, device offset with --offset
|
||||
and hash algorithm using --hash, see man page for details.
|
||||
|
||||
Please note that loopAES dm-crypt mode is provided for compatibility reasons
|
||||
(so you do not need to patch kernel and util-linux to map existing volumes)
|
||||
but it is not, and never will be, optimized for speed.
|
||||
It is experimental feature for now.
|
||||
|
||||
* Require the whole key read from keyfile in create command (regression in 1.2.0).
|
||||
|
||||
* WARNING: This is the last cryptsetup release which supports library with
|
||||
old API (using struct crypt_options).
|
||||
These calls are deprecated since 1.1.0 and AFAIK no application
|
||||
is using it in recent distros. Removing compatible code will allow
|
||||
new features to be implemented easily.
|
||||
|
||||
Other changes
|
||||
~~~~~~~~~~~~~
|
||||
* Lock memory also in luksDump command.
|
||||
* Fix return code when passphrase is read from pipe.
|
||||
* Increase libcryptsetup version (loopAES change), still fully backward compatible.
|
||||
* Fixes static build (--disable-static-cryptsetup now works properly).
|
||||
* Supports secure data flag for device-mapper ioctl (will be in 2.6.39,
|
||||
forcing kernel to wipe all ioctl buffers with possible key data).
|
||||
To enable this flag you need new device-mapper library, in LVM2 2.02.84.
|
||||
* Add copyright texts into some files and adds GPL exception allowing
|
||||
to distribute resulting binaries linked with OpenSSL.
|
||||
* Update FAQ.
|
||||
* Fix message when locking memory fails.
|
||||
* Fix luksAddKey return code if master key is used.
|
||||
* Update some text files in distributions.
|
||||
* Add docs directory with Release Notes archive.
|
||||
* Do not hardcode loopback device name in tests, use internal loopback library.
|
||||
14
docs/v1.3.1-ReleaseNotes
Normal file
14
docs/v1.3.1-ReleaseNotes
Normal file
@@ -0,0 +1,14 @@
|
||||
Cryptsetup 1.3.1 Release Notes
|
||||
==============================
|
||||
|
||||
Changes since version 1.3.0
|
||||
|
||||
* Fix keyfile=- processing in create command (regression in 1.3.0).
|
||||
|
||||
* Simplify device path status check (use /sys and do not scan /dev).
|
||||
|
||||
* Do not ignore device size argument for create command (regression in 1.2.0).
|
||||
|
||||
* Fix error paths in blockwise code and lseek_write call.
|
||||
|
||||
* Add optional Nettle crypto backend support.
|
||||
131
docs/v1.4.0-ReleaseNotes
Normal file
131
docs/v1.4.0-ReleaseNotes
Normal file
@@ -0,0 +1,131 @@
|
||||
Cryptsetup 1.4.0 Release Notes
|
||||
==============================
|
||||
|
||||
Changes since version 1.3.1
|
||||
|
||||
Important changes
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
WARNING: This release removes old deprecated API from libcryptsetup
|
||||
(all functions using struct crypt_options).
|
||||
|
||||
This require libcrypsetup version change and
|
||||
rebuild of applications using cryptsetup library.
|
||||
All new API symbols are backward compatible.
|
||||
|
||||
* If device is not rotational disk, cryptsetup no longer tries
|
||||
to wipe keyslot with Gutmann algorithm for magnetic media erase
|
||||
but simply rewrites area once by random data.
|
||||
|
||||
* The on-disk LUKS header can now be detached (e.g. placed on separate
|
||||
device or in file) using new --header option.
|
||||
|
||||
This option is only relevant for LUKS devices and can be used in
|
||||
luksFormat, luksOpen, luksSuspend, luksResume and resize commands.
|
||||
|
||||
If used with luksFormat the --align-payload option is taken
|
||||
as absolute sector alignment on ciphertext device and can be zero.
|
||||
|
||||
Example:
|
||||
Create LUKS device with ciphertext device on /dev/sdb and header
|
||||
on device /dev/sdc. Use all space on /dev/sdb (no reserved area for header).
|
||||
|
||||
cryptsetup luksFormat /dev/sdb --header /dev/sdc --align-payload 0
|
||||
|
||||
Activate such device:
|
||||
cryptsetup luksOpen /dev/sdb --header /dev/sdc test_disk
|
||||
|
||||
You can use file for LUKS header (loop device will be used while
|
||||
manipulating with such detached header), just you have to create
|
||||
large enough file in advance.
|
||||
|
||||
dd if=/dev/zero of=/mnt/luks_header bs=1M count=4
|
||||
cryptsetup luksFormat /dev/sdb --header /mnt/luks_header --align-payload 0
|
||||
|
||||
Activation is the same as above.
|
||||
|
||||
cryptsetup luksOpen /dev/sdb --header /mnt/luks_header test_disk
|
||||
|
||||
All keyslot operations need to be run on _header_ not on ciphertext device,
|
||||
an example:
|
||||
|
||||
cryptsetup luksAddKey /mnt/luks_header
|
||||
|
||||
If you do not use --align-payload 0, you can later restore LUKS header
|
||||
on device itself (and use it as normal LUKS device without detached header).
|
||||
|
||||
WARNING: There is no possible check that specified ciphertext device
|
||||
matches detached on-disk header. Use with care, it can destroy
|
||||
your data in case of a mistake.
|
||||
|
||||
WARNING: Storing LUKS header in a file means that anti-forensic splitter
|
||||
cannot properly work (there is filesystem allocation layer between
|
||||
header and disk).
|
||||
|
||||
* Support --allow-discards option to allow discards/TRIM requests.
|
||||
|
||||
Since kernel 3.1, dm-crypt devices optionally (not by default) support
|
||||
block discards (TRIM) commands.
|
||||
If you want to enable this operation, you have to enable it manually
|
||||
on every activation using --allow-discards
|
||||
|
||||
cryptsetup luksOpen --allow-discards /dev/sdb test_disk
|
||||
|
||||
WARNING: There are several security consequences, please read at least
|
||||
http://asalor.blogspot.com/2011/08/trim-dm-crypt-problems.html
|
||||
before you enable it.
|
||||
|
||||
* Add --shared option for creating non-overlapping crypt segments.
|
||||
|
||||
The --shared options checks that mapped segments are not overlapping
|
||||
and allows non-exclusive access to underlying device.
|
||||
Only plain crypt devices can be used in this mode.
|
||||
|
||||
Example - map 64M of device disk and following 32 M area as another disk.
|
||||
|
||||
cryptsetup create outer_disk /dev/sdb --offset 0 --size 65536
|
||||
cryptsetup create inner_disk /dev/sdb --offset 65536 --size 32768 --shared
|
||||
|
||||
(It can be used to simulate trivial hidden disk concepts.)
|
||||
|
||||
libcryptsetup API changes:
|
||||
* Added options to suport detached metadata device
|
||||
crypt_init_by_name_and_header()
|
||||
crypt_set_data_device()
|
||||
* Add crypt_last_error() API call.
|
||||
* Fix plain crypt format parameters to include size option.
|
||||
* Add crypt_get_iv_offset() function.
|
||||
|
||||
* Remove old API functions (all functions using crypt_options).
|
||||
|
||||
* Support key-slot option for luksOpen (use only explicit keyslot).
|
||||
|
||||
You can now specify key slot in luksOpen and limit checking
|
||||
only to specified slot.
|
||||
|
||||
* Support retries and timeout parameters for luksSuspend.
|
||||
(The same way as in luksOpen.)
|
||||
|
||||
* Add doxygen-like documentation (it will be available on project page later).
|
||||
(To generate it manually run doxygen in docs directory.)
|
||||
|
||||
Other changes
|
||||
~~~~~~~~~~~~~
|
||||
* Fix crypt_load to properly check device size.
|
||||
* Do not allow context format of already formatted device.
|
||||
* Do not allow key retrieval while suspended (key could be wiped).
|
||||
* Do not allow suspend for non-LUKS devices.
|
||||
* Fix luksKillSLot exit code if slot is inactive or invalid.
|
||||
* Fix exit code if passphrases do not match in luksAddKey.
|
||||
* Fix return code for status command when device doesn't exists.
|
||||
* Fix verbose messages in isLuks command.
|
||||
* Support Nettle 2.4 crypto backend (supports ripemd160).
|
||||
* Add LUKS on-disk format description into package.
|
||||
* Enhance check of device size before writing LUKS header.
|
||||
* Add more paranoid checks for LUKS header and keyslot attributes.
|
||||
* Use new /dev/loop-control (kernel 3.1) if possible.
|
||||
* Remove hash/hmac restart from crypto backend and make it part of hash/hmac final.
|
||||
* Improve check for invalid offset and size values.
|
||||
* Revert default initialisation of volume key in crypt_init_by_name().
|
||||
* Add more regression tests.
|
||||
* Add some libcryptsetup example files (see docs/examples).
|
||||
25
docs/v1.4.1-ReleaseNotes
Normal file
25
docs/v1.4.1-ReleaseNotes
Normal file
@@ -0,0 +1,25 @@
|
||||
Cryptsetup 1.4.1 Release Notes
|
||||
==============================
|
||||
|
||||
Changes since version 1.4.0
|
||||
|
||||
* Merge experimental Python cryptsetup (pycryptsetup) binding.
|
||||
|
||||
This option is disabled by default, you can enable build of Python binding
|
||||
with --enable--python configure switch.
|
||||
|
||||
Note that binding currently covers only partial libcryptsetup functions,
|
||||
mainly LUKS device handling needed for Anaconda installer.
|
||||
Until now provided separately as python-cryptsetup.
|
||||
Thanks to Martin Sivak for the code.
|
||||
|
||||
See python subdirectory for more info.
|
||||
|
||||
Python binding code is experimental for now, no stable API guarantee.
|
||||
|
||||
* Fix crypt_get_volume_key_size() for plain device.
|
||||
(cryptsetup status reported zero key size for plain crypt devices).
|
||||
|
||||
* Fix typo in set_iteration_time API call (old name remains for compatibility reasons).
|
||||
|
||||
* Fix FSF address in license and add LGPL license text.
|
||||
44
docs/v1.4.2-ReleaseNotes
Normal file
44
docs/v1.4.2-ReleaseNotes
Normal file
@@ -0,0 +1,44 @@
|
||||
Cryptsetup 1.4.2 Release Notes
|
||||
==============================
|
||||
|
||||
Changes since version 1.4.1
|
||||
|
||||
* Add --keyfile-offset and --new-keyfile-offset parameters to API and CLI.
|
||||
These options can be used to skip start of keyfile or device used as keyfile.
|
||||
|
||||
* Add repair command and crypt_repair() for known LUKS metadata problems repair.
|
||||
|
||||
Some well-known LUKS metadata corruptions are easy to repair, this
|
||||
command should provide a way to fix these problems.
|
||||
|
||||
Always create binary backup of header device before running repair,
|
||||
(only 4kB - visible header) for example by using dd:
|
||||
dd if=/dev/<LUKS header device> of=repair_bck.img bs=1k count=4
|
||||
|
||||
Then you can try to run repair:
|
||||
cryptsetup repair <device>
|
||||
|
||||
Note, not all problems are possible to repair and if keyslot or some header
|
||||
parameters are overwritten, device is lost permanently.
|
||||
|
||||
* Fix header check to support old (cryptsetup 1.0.0) header alignment.
|
||||
(Regression in 1.4.0)
|
||||
|
||||
* Allow to specify --align-payload only for luksFormat.
|
||||
|
||||
* Add --master-key-file option to luksOpen (open using volume key).
|
||||
|
||||
* Support UUID=<LUKS_UUID> format for device specification.
|
||||
You can open device by UUID (only shortcut to /dev/disk/by-uuid/ symlinks).
|
||||
|
||||
* Support password verification with quiet flag if possible. (1.2.0)
|
||||
Password verification can be still possible if input is terminal.
|
||||
|
||||
* Fix retry if entered passphrases (with verify option) do not match.
|
||||
(It should retry if requested, not fail.)
|
||||
|
||||
* Fix use of empty keyfile.
|
||||
|
||||
* Fix error message for luksClose and detached LUKS header.
|
||||
|
||||
* Allow --header for status command to get full info with detached header.
|
||||
62
docs/v1.4.3-ReleaseNotes
Normal file
62
docs/v1.4.3-ReleaseNotes
Normal file
@@ -0,0 +1,62 @@
|
||||
Cryptsetup 1.4.3 Release Notes
|
||||
==============================
|
||||
|
||||
Changes since version 1.4.2
|
||||
|
||||
* Fix readonly activation if underlying device is readonly (1.4.0).
|
||||
|
||||
* Fix loop mapping on readonly file.
|
||||
|
||||
* Include stddef.h in libdevmapper.h (size_t definition).
|
||||
|
||||
* Fix keyslot removal for device with 4k hw block (1.4.0).
|
||||
(Wipe keyslot failed in this case.)
|
||||
|
||||
* Relax --shared flag to allow mapping even for overlapping segments.
|
||||
|
||||
The --shared flag (and API CRYPT_ACTIVATE_SHARED flag) is now able
|
||||
to map arbitrary overlapping area. From API it is even usable
|
||||
for LUKS devices.
|
||||
It is user responsibility to not cause data corruption though.
|
||||
|
||||
This allows e.g. scubed to work again and also allows some
|
||||
tricky extensions later.
|
||||
|
||||
* Allow empty cipher (cipher_null) for testing.
|
||||
|
||||
You can now use "null" (or directly cipher_null-ecb) in cryptsetup.
|
||||
This means no encryption, useful for performance tests
|
||||
(measure dm-crypt layer overhead).
|
||||
|
||||
* Switch on retry on device remove for libdevmapper.
|
||||
Device-mapper now retry removal if device is busy.
|
||||
|
||||
* Allow "private" activation (skip some udev global rules) flag.
|
||||
Cryptsetup library API now allows to specify CRYPT_ACTIVATE_PRIVATE,
|
||||
which means that some udev rules are not processed.
|
||||
(Used for temporary devices, like internal keyslot mappings where
|
||||
it is not desirable to run any device scans.)
|
||||
|
||||
* This release also includes some Red Hat/Fedora specific extensions
|
||||
related to FIPS140-2 compliance.
|
||||
|
||||
In fact, all these patches are more formal changes and are just subset
|
||||
of building blocks for FIPS certification. See FAQ for more details
|
||||
about FIPS.
|
||||
|
||||
FIPS extensions are enabled by using --enable-fips configure switch.
|
||||
|
||||
In FIPS mode (kernel booted with fips=1 and gcrypt in FIPS mode)
|
||||
|
||||
- it provides library and binary integrity verification using
|
||||
libfipscheck (requires pre-generated checksums)
|
||||
|
||||
- it uses FIPS approved RNG for encryption key and salt generation
|
||||
(note that using /dev/random is not formally FIPS compliant RNG).
|
||||
|
||||
- only gcrypt crypto backend is currently supported in FIPS mode.
|
||||
|
||||
The FIPS RNG requirement for salt comes from NIST SP 800-132 recommendation.
|
||||
(Recommendation for Password-Based Key Derivation. Part 1: Storage Applications.
|
||||
http://csrc.nist.gov/publications/nistpubs/800-132/nist-sp800-132.pdf)
|
||||
LUKS should be aligned to this recommendation otherwise.
|
||||
241
docs/v1.5.0-ReleaseNotes
Normal file
241
docs/v1.5.0-ReleaseNotes
Normal file
@@ -0,0 +1,241 @@
|
||||
Cryptsetup 1.5.0 Release Notes
|
||||
==============================
|
||||
|
||||
This release covers mainly inclusion of:
|
||||
|
||||
* Veritysetup tool (and related libcryptsetup extensions for dm-verity).
|
||||
|
||||
* Experimental cryptsetup-reencrypt tool (LUKS offline reencryption).
|
||||
|
||||
Changes since version 1.5.0-rc2
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* Add --device-size option for reencryption tool.
|
||||
|
||||
* Switch to use unit suffix for --reduce-device-size option.
|
||||
|
||||
* Remove open device debugging feature (no longer needed).
|
||||
|
||||
* Fix library name for FIPS check.
|
||||
|
||||
* Add example of using reencryption inside dracut (see misc/dracut).
|
||||
|
||||
Changes since version 1.5.0-rc1
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Introduce cryptsetup-reencrypt - experimental offline LUKS reencryption tool.
|
||||
|
||||
! cryptsetup-reencrypt tool is EXPERIMENTAL
|
||||
! ALWAYS BE SURE YOU HAVE RELIABLE BACKUP BEFORE USING THIS TOOL
|
||||
|
||||
This tool tries to simplify situation when you need to re-encrypt the whole
|
||||
LUKS device in situ (without need to move data elsewhere).
|
||||
|
||||
This can happen for example when you want to change volume (master) key,
|
||||
encryption algorithm, or other encryption parameter.
|
||||
|
||||
Cryptsetup-reencrypt can even optionally shift data on device
|
||||
(reducing data device size - you need some free space at the end of device).
|
||||
|
||||
In general, cryptsetup-reencrypt can be used to
|
||||
|
||||
- re-generate volume key
|
||||
- change arbitrary encryption parameters
|
||||
- add encryption to not yet encrypted drive
|
||||
|
||||
Side effect of reencryption is that final device will contain
|
||||
only ciphertext (for all sectors) so even if device was not properly
|
||||
wiped by random data, after reencryption you cannot distinguish
|
||||
which sectors are used.
|
||||
(Reecryption is done always for the whole device.)
|
||||
|
||||
There are for sure bugs, please TEST IT IN TEST ENVIRONMENT before
|
||||
use for your data.
|
||||
|
||||
This tool is not resistant to HW and kernel failures - hw crash
|
||||
will cause serious data corruption.
|
||||
|
||||
You can enable compilation of this tool with --enable-cryptsetup-reencrypt
|
||||
configure option (it is switched off by default).
|
||||
(Tool requires libcryptsetup 1.4.3 and later.)
|
||||
|
||||
You have to provide all keyslot passphrases or use --keyslot-option
|
||||
(then all other keyslots will be disabled).
|
||||
|
||||
EXAMPLES (from man page)
|
||||
|
||||
Reencrypt /dev/sdb1 (change volume key)
|
||||
# cryptsetup-reencrypt /dev/sdb1
|
||||
|
||||
Reencrypt and also change cipher and cipher mode
|
||||
# cryptsetup-reencrypt /dev/sdb1 -c aes-xts-plain64
|
||||
|
||||
Note: if you are changing key size, there must be enough space
|
||||
for keyslots in header or you have to use --reduce-device size and
|
||||
reduce fs in advance.
|
||||
|
||||
Add LUKS encryption to not yet encrypted device
|
||||
First, be sure you have space added to disk.
|
||||
Or, alternatively, shrink filesystem in advance.
|
||||
|
||||
Here we need 4096 512-bytes sectors (enough for 2x128 bit key).
|
||||
|
||||
# fdisk -u /dev/sdb # move sdb1 partition end + 4096 sectors
|
||||
|
||||
# cryptsetup-reencrypt /dev/sdb1 --new --reduce-device-size 4096
|
||||
|
||||
There are some options which can improve performance (depends on system),
|
||||
namely --use-directio (use direct IO for all operations) can be faster
|
||||
on some systems. See man page.
|
||||
|
||||
Progress and estimated time is printed during reencryption.
|
||||
|
||||
You can suspend reencryption (using ctrl+c or term signal).
|
||||
To continue reencryption you have to provide only
|
||||
the device parameter (offset is stored in temporary log file).
|
||||
|
||||
Please note LUKS device is marked invalid during reencryption and
|
||||
you have to retain tool temporary files until reencryption finishes.
|
||||
|
||||
Temporary files are LUKS-<uuid>.[log|org|new]
|
||||
|
||||
Other changes
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
* Fix luks-header-from-active script (do not use LUKS header on-disk, add UUID).
|
||||
|
||||
* Add --test-passphrase option for luksOpen (check passphrase only).
|
||||
|
||||
* Fix parsing of hexadecimal string (salt or root hash) in veritysetup.
|
||||
|
||||
Changes since version 1.4.3
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Introduce veritysetup tool for dm-verity target management.
|
||||
|
||||
The dm-verity device-mapper target was added to Linux kernel 3.4 and
|
||||
provides transparent integrity checking of block devices using a cryptographic
|
||||
digest provided by the kernel crypto API. This target is read-only.
|
||||
|
||||
It is meant to be setup as part of a verified boot path (it was originally
|
||||
developed by Chrome OS authors as part of verified boot infrastructure).
|
||||
|
||||
For deeper description please see http://code.google.com/p/cryptsetup/wiki/DMVerity
|
||||
and kernel dm-verity documentation.
|
||||
|
||||
The libcryptsetup library was extended to support manipulation
|
||||
with dm-verity kernel module and new veritysetup CLI tool is added.
|
||||
|
||||
There are no additional library requirements (it uses the same crypto
|
||||
backend as cryptsetup).
|
||||
|
||||
If you want compile cryptsetup without veritysetup tool,
|
||||
use --disable-veritysetup configure option.
|
||||
For other configuration option see configure --help and veritysetup --help
|
||||
(e.g. default parameters).
|
||||
|
||||
Supported libcryptsetup functions new CRYPT_VERITY type:
|
||||
crypt_init
|
||||
crypt_init_by_name
|
||||
crypt_set_data device
|
||||
crypt_get_type
|
||||
crypt_format
|
||||
crypt_load
|
||||
crypt_get_active_device
|
||||
crypt_activate_by_volume_key (volume key == root hash here)
|
||||
crypt_dump
|
||||
and new introduced function
|
||||
crypt_get_verity_info
|
||||
|
||||
Please see comments in libcryptsetup.h and veritysetup.c as an code example
|
||||
how to use CRYPT_VERITY API.
|
||||
|
||||
The veritysetup tool supports these operations:
|
||||
|
||||
veritysetup format <data_device> <hash_device>
|
||||
Formats <hash_device> (calculates all hash areas according to <data_device>).
|
||||
This is initial command to prepare device <hash_device> for later verification.
|
||||
|
||||
veritysetup create <name> <data_device> <hash_device> <root_hash>
|
||||
Creates (activates) a dm-verity mapping with <name> backed by device <data_device>
|
||||
and using <hash_device> for in-kernel verification.
|
||||
|
||||
veritysetup verify <data_device> <hash_device> <root_hash>
|
||||
Verifies data in userspace (no kernel device is activated).
|
||||
|
||||
veritysetup remove <name>
|
||||
Removes activated device from kernel (similar to dmsetup remove).
|
||||
|
||||
veritysetup status <name>
|
||||
Reports status for the active kernel dm-verity device.
|
||||
|
||||
veritysetup dump <hash_device>
|
||||
Reports parameters of verity device from on-disk stored superblock.
|
||||
|
||||
For more info see veritysetup --help and veritysetup man page.
|
||||
|
||||
Other changes
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
* Both data and header device can now be a file and
|
||||
loop device is automatically allocated.
|
||||
|
||||
* Require only up to last keyslot area for header device, previously
|
||||
backup (and activation) required device/file of size up to data start
|
||||
offset (data payload).
|
||||
|
||||
* Fix header backup and restore to work on files with large data offset.
|
||||
Backup and restore now works even if backup file is smaller than data offset.
|
||||
|
||||
Appendix: Examples of veritysetup use
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Format device using default parameters, info and final root hash is printed:
|
||||
# veritysetup format /dev/sdb /dev/sdc
|
||||
VERITY header information for /dev/sdc
|
||||
UUID: fad30431-0c59-4fa6-9b57-732a90501f75
|
||||
Hash type: 1
|
||||
Data blocks: 52224
|
||||
Data block size: 4096
|
||||
Hash block size: 4096
|
||||
Hash algorithm: sha256
|
||||
Salt: 5cc52759af76a092e0c21829cd0ef6938f69831bf86926525106f92a7e9e3aa9
|
||||
Root hash: 7aefa4506f7af497ac491a27f862cf8005ea782a5d97f6426945a6896ab557a1
|
||||
|
||||
Activation of device in-kernel:
|
||||
# veritysetup create vr /dev/sdb /dev/sdc 7aefa4506f7af497ac491a27f862cf8005ea782a5d97f6426945a6896ab557a1
|
||||
Note - if device is corrupted, kernel mapping is created but will report failure:
|
||||
Verity device detected corruption after activation.
|
||||
|
||||
Userspace verification:
|
||||
# veritysetup verify /dev/sdb /dev/sdc 7aefa4506f7af497ac491a27f862cf8005ea782a5d97f6426945a6896ab557a1
|
||||
Verification failed at position 8192.
|
||||
Verification of data area failed.
|
||||
|
||||
Active device status report:
|
||||
# veritysetup status vr
|
||||
/dev/mapper/vr is active.
|
||||
type: VERITY
|
||||
status: verified
|
||||
hash type: 1
|
||||
data block: 4096
|
||||
hash block: 4096
|
||||
hash name: sha256
|
||||
salt: 5cc52759af76a092e0c21829cd0ef6938f69831bf86926525106f92a7e9e3aa9
|
||||
data device: /dev/sdb
|
||||
size: 417792 sectors
|
||||
mode: readonly
|
||||
hash device: /dev/sdc
|
||||
hash offset: 8 sectors
|
||||
|
||||
Dump of on-disk superblock information:
|
||||
# veritysetup dump /dev/sdc
|
||||
VERITY header information for /dev/sdc
|
||||
UUID: fad30431-0c59-4fa6-9b57-732a90501f75
|
||||
Hash type: 1
|
||||
Data blocks: 52224
|
||||
Data block size: 4096
|
||||
Hash block size: 4096
|
||||
Hash algorithm: sha256
|
||||
Salt: 5cc52759af76a092e0c21829cd0ef6938f69831bf86926525106f92a7e9e3aa9
|
||||
|
||||
Remove mapping:
|
||||
# veritysetup remove vr
|
||||
@@ -1,32 +1,16 @@
|
||||
SUBDIRS = crypto_backend luks1 loopaes verity
|
||||
|
||||
moduledir = $(libdir)/cryptsetup
|
||||
|
||||
if BUILD_LIBDEVMAPPER
|
||||
_LIBDEVMAPPER_LIBADD = @LIBDEVMAPPER_LIBS@
|
||||
_LIBDEVMAPPER_SOURCES = libdevmapper.c
|
||||
_LIBDEVMAPPER_CFLAGS = -DBUILTIN_LIBDEVMAPPER
|
||||
endif
|
||||
libbbackend_devmapper_la_SOURCES = libdevmapper.c
|
||||
libbbackend_devmapper_la_LDFLAGS = -avoid-version -module
|
||||
libbbackend_devmapper_la_LIBADD = @LIBDEVMAPPER_LIBS@
|
||||
if SHARED_LIBDEVMAPPER
|
||||
_LIBDEVMAPPER_SHLIB = libbbackend_devmapper.la
|
||||
endif
|
||||
|
||||
if BUILD_LIBGCRYPT
|
||||
_LIBGCRYPT_LIBADD = @LIBGCRYPT_LIBS@
|
||||
_LIBGCRYPT_SOURCES = gcrypt.c
|
||||
_LIBGCRYPT_CFLAGS = -DBUILTIN_GCRYPT
|
||||
endif
|
||||
libcrypto_gcrypt_la_SOURCES = gcrypt.c
|
||||
libcrypto_gcrypt_la_LDFLAGS = -avoid-version -module
|
||||
libcrypto_gcrypt_la_LIBADD = @LIBGCRYPT_LIBS@
|
||||
if SHARED_LIBGCRYPT
|
||||
_LIBGCRYPT_SHLIB = libcrypto_gcrypt.la
|
||||
endif
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = libcryptsetup.pc
|
||||
|
||||
INCLUDES = \
|
||||
-I$(top_srcdir) \
|
||||
-I$(top_srcdir)/luks \
|
||||
-I$(top_srcdir)/lib/crypto_backend \
|
||||
-I$(top_srcdir)/lib/luks1 \
|
||||
-I$(top_srcdir)/lib/loopaes \
|
||||
-I$(top_srcdir)/lib/verity \
|
||||
-DDATADIR=\""$(datadir)"\" \
|
||||
-DLIBDIR=\""$(libdir)"\" \
|
||||
-DPREFIX=\""$(prefix)"\" \
|
||||
@@ -34,43 +18,53 @@ INCLUDES = \
|
||||
-DVERSION=\""$(VERSION)"\" \
|
||||
-D_GNU_SOURCE \
|
||||
-D_LARGEFILE64_SOURCE \
|
||||
-D_FILE_OFFSET_BITS=64 \
|
||||
@LIBDEVMAPPER_CFLAGS@ \
|
||||
$(_LIBDEVMAPPER_CFLAGS) \
|
||||
@LIBGCRYPT_CFLAGS@ \
|
||||
$(_LIBGCRYPT_CFLAGS)
|
||||
-D_FILE_OFFSET_BITS=64
|
||||
|
||||
lib_LTLIBRARIES = \
|
||||
libcryptsetup.la
|
||||
lib_LTLIBRARIES = libcryptsetup.la
|
||||
|
||||
module_LTLIBRARIES = \
|
||||
$(_LIBDEVMAPPER_SHLIB) \
|
||||
$(_LIBGCRYPT_SHLIB)
|
||||
common_ldadd = \
|
||||
crypto_backend/libcrypto_backend.la \
|
||||
luks1/libluks1.la \
|
||||
loopaes/libloopaes.la \
|
||||
verity/libverity.la
|
||||
|
||||
if STATIC_LIBRARY
|
||||
_STATIC_LIBRARY = -static
|
||||
endif
|
||||
libcryptsetup_la_DEPENDENCIES = $(common_ldadd) libcryptsetup.sym
|
||||
|
||||
libcryptsetup_la_LDFLAGS = \
|
||||
$(_STATIC_LIBRARY)
|
||||
-Wl,--version-script=$(top_srcdir)/lib/libcryptsetup.sym \
|
||||
-version-info @LIBCRYPTSETUP_VERSION_INFO@
|
||||
|
||||
libcryptsetup_la_CFLAGS = -Wall
|
||||
libcryptsetup_la_CFLAGS = -Wall @CRYPTO_CFLAGS@
|
||||
|
||||
libcryptsetup_la_LIBADD = \
|
||||
$(_LIBDEVMAPPER_LIBADD) \
|
||||
$(_LIBGCRYPT_LIBADD) \
|
||||
@UUID_LIBS@ \
|
||||
../luks/libluks.la
|
||||
@DEVMAPPER_LIBS@ \
|
||||
@CRYPTO_LIBS@ \
|
||||
@FIPSCHECK_LIBS@ \
|
||||
$(common_ldadd)
|
||||
|
||||
|
||||
libcryptsetup_la_SOURCES = \
|
||||
setup.c \
|
||||
internal.h \
|
||||
blockdev.h \
|
||||
bitops.h \
|
||||
nls.h \
|
||||
libcryptsetup.h \
|
||||
utils.c \
|
||||
backends.c \
|
||||
$(_LIBDEVMAPPER_SOURCES) \
|
||||
$(_LIBGCRYPT_SOURCES)
|
||||
utils_crypt.c \
|
||||
utils_crypt.h \
|
||||
utils_loop.c \
|
||||
utils_loop.h \
|
||||
utils_devpath.c \
|
||||
utils_wipe.c \
|
||||
utils_fips.c \
|
||||
utils_fips.h \
|
||||
libdevmapper.c \
|
||||
utils_dm.h \
|
||||
volumekey.c \
|
||||
random.c \
|
||||
crypt_plain.c
|
||||
|
||||
include_HEADERS = \
|
||||
libcryptsetup.h
|
||||
include_HEADERS = libcryptsetup.h
|
||||
|
||||
EXTRA_DIST = libcryptsetup.pc.in libcryptsetup.sym
|
||||
|
||||
135
lib/backends.c
135
lib/backends.c
@@ -1,135 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "libcryptsetup.h"
|
||||
#include "internal.h"
|
||||
|
||||
extern struct hash_backend hash_gcrypt_backend;
|
||||
extern struct setup_backend setup_libdevmapper_backend;
|
||||
|
||||
#ifdef USE_PLUGINS
|
||||
static void init_plugins(void)
|
||||
{
|
||||
}
|
||||
#else /* USE_PLUGINS */
|
||||
# define init_plugins() do { } while(0)
|
||||
#endif /* USE_PLUGINS */
|
||||
|
||||
static struct hash_backend *hash_backends[] = {
|
||||
#ifdef BUILTIN_GCRYPT
|
||||
&hash_gcrypt_backend,
|
||||
#endif
|
||||
NULL
|
||||
};
|
||||
|
||||
static struct setup_backend *setup_backends[] = {
|
||||
#ifdef BUILTIN_LIBDEVMAPPER
|
||||
&setup_libdevmapper_backend,
|
||||
#endif
|
||||
NULL
|
||||
};
|
||||
|
||||
struct hash_backend *get_hash_backend(const char *name)
|
||||
{
|
||||
struct hash_backend **backend;
|
||||
|
||||
init_plugins();
|
||||
|
||||
for(backend = hash_backends; *backend; backend++)
|
||||
if (!name || strcmp(name, (*backend)->name) == 0)
|
||||
break;
|
||||
|
||||
return *backend;
|
||||
}
|
||||
|
||||
void put_hash_backend(struct hash_backend *backend)
|
||||
{
|
||||
}
|
||||
|
||||
int hash(const char *backend_name, const char *hash_name,
|
||||
char *result, size_t size,
|
||||
const char *passphrase, size_t sizep)
|
||||
{
|
||||
struct hash_backend *backend;
|
||||
struct hash_type *hashes = NULL, *hash;
|
||||
char hash_name_buf[256], *s;
|
||||
size_t pad = 0;
|
||||
int r = -ENOENT;
|
||||
|
||||
if (strlen(hash_name) >= sizeof(hash_name_buf)) {
|
||||
set_error("hash name too long: %s", hash_name);
|
||||
return -ENAMETOOLONG;
|
||||
}
|
||||
|
||||
if ((s = strchr(hash_name, ':'))) {
|
||||
size_t hlen;
|
||||
strcpy(hash_name_buf, hash_name);
|
||||
hash_name_buf[s-hash_name] = '\0';
|
||||
hash_name = hash_name_buf;
|
||||
hlen = atoi(++s);
|
||||
if (hlen > size) {
|
||||
set_error("requested hash length (%zd) > key length (%zd)", hlen, size);
|
||||
return -EINVAL;
|
||||
}
|
||||
pad = size-hlen;
|
||||
size = hlen;
|
||||
}
|
||||
|
||||
backend = get_hash_backend(backend_name);
|
||||
if (!backend) {
|
||||
set_error("No hash backend found");
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
hashes = backend->get_hashes();
|
||||
if (!hashes) {
|
||||
set_error("No hash functions available");
|
||||
goto out;
|
||||
}
|
||||
|
||||
for(hash = hashes; hash->name; hash++)
|
||||
if (strcmp(hash->name, hash_name) == 0)
|
||||
break;
|
||||
if (!hash->name) {
|
||||
set_error("Unknown hash type %s", hash_name);
|
||||
goto out;
|
||||
}
|
||||
|
||||
r = hash->fn(hash->private, size, result, sizep, passphrase);
|
||||
if (r < 0) {
|
||||
set_error("Error hashing passphrase");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (pad) {
|
||||
memset(result+size, 0, pad);
|
||||
}
|
||||
|
||||
out:
|
||||
if (hashes)
|
||||
backend->free_hashes(hashes);
|
||||
put_hash_backend(backend);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
struct setup_backend *get_setup_backend(const char *name)
|
||||
{
|
||||
struct setup_backend **backend;
|
||||
|
||||
init_plugins();
|
||||
|
||||
for(backend = setup_backends; *backend; backend++)
|
||||
if (!name || strcmp(name, (*backend)->name) == 0)
|
||||
break;
|
||||
|
||||
return *backend;
|
||||
}
|
||||
|
||||
void put_setup_backend(struct setup_backend *backend)
|
||||
{
|
||||
#ifdef USE_PLUGINS
|
||||
#endif
|
||||
}
|
||||
83
lib/bitops.h
Normal file
83
lib/bitops.h
Normal file
@@ -0,0 +1,83 @@
|
||||
#ifndef BITOPS_H
|
||||
#define BITOPS_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/*
|
||||
* Bit map related macros. Usually provided by libc.
|
||||
*/
|
||||
#include <sys/param.h>
|
||||
|
||||
#ifndef NBBY
|
||||
# define NBBY CHAR_BIT
|
||||
#endif
|
||||
|
||||
#ifndef setbit
|
||||
# define setbit(a,i) ((a)[(i)/NBBY] |= 1<<((i)%NBBY))
|
||||
# define clrbit(a,i) ((a)[(i)/NBBY] &= ~(1<<((i)%NBBY)))
|
||||
# define isset(a,i) ((a)[(i)/NBBY] & (1<<((i)%NBBY)))
|
||||
# define isclr(a,i) (((a)[(i)/NBBY] & (1<<((i)%NBBY))) == 0)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Byte swab macros (based on linux/byteorder/swab.h)
|
||||
*/
|
||||
#define swab16(x) \
|
||||
((uint16_t)( \
|
||||
(((uint16_t)(x) & (uint16_t)0x00ffU) << 8) | \
|
||||
(((uint16_t)(x) & (uint16_t)0xff00U) >> 8) ))
|
||||
|
||||
#define swab32(x) \
|
||||
((uint32_t)( \
|
||||
(((uint32_t)(x) & (uint32_t)0x000000ffUL) << 24) | \
|
||||
(((uint32_t)(x) & (uint32_t)0x0000ff00UL) << 8) | \
|
||||
(((uint32_t)(x) & (uint32_t)0x00ff0000UL) >> 8) | \
|
||||
(((uint32_t)(x) & (uint32_t)0xff000000UL) >> 24) ))
|
||||
|
||||
#define swab64(x) \
|
||||
((uint64_t)( \
|
||||
(uint64_t)(((uint64_t)(x) & (uint64_t)0x00000000000000ffULL) << 56) | \
|
||||
(uint64_t)(((uint64_t)(x) & (uint64_t)0x000000000000ff00ULL) << 40) | \
|
||||
(uint64_t)(((uint64_t)(x) & (uint64_t)0x0000000000ff0000ULL) << 24) | \
|
||||
(uint64_t)(((uint64_t)(x) & (uint64_t)0x00000000ff000000ULL) << 8) | \
|
||||
(uint64_t)(((uint64_t)(x) & (uint64_t)0x000000ff00000000ULL) >> 8) | \
|
||||
(uint64_t)(((uint64_t)(x) & (uint64_t)0x0000ff0000000000ULL) >> 24) | \
|
||||
(uint64_t)(((uint64_t)(x) & (uint64_t)0x00ff000000000000ULL) >> 40) | \
|
||||
(uint64_t)(((uint64_t)(x) & (uint64_t)0xff00000000000000ULL) >> 56) ))
|
||||
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
|
||||
#define cpu_to_le16(x) swab16(x)
|
||||
#define cpu_to_le32(x) swab32(x)
|
||||
#define cpu_to_le64(x) swab64(x)
|
||||
#define cpu_to_be16(x) ((uint16_t)(x))
|
||||
#define cpu_to_be32(x) ((uint32_t)(x))
|
||||
#define cpu_to_be64(x) ((uint64_t)(x))
|
||||
|
||||
#define le16_to_cpu(x) swab16(x)
|
||||
#define le32_to_cpu(x) swab32(x)
|
||||
#define le64_to_cpu(x) swab64(x)
|
||||
#define be16_to_cpu(x) ((uint16_t)(x))
|
||||
#define be32_to_cpu(x) ((uint32_t)(x))
|
||||
#define be64_to_cpu(x) ((uint64_t)(x))
|
||||
|
||||
#else /* !WORDS_BIGENDIAN */
|
||||
|
||||
#define cpu_to_le16(x) ((uint16_t)(x))
|
||||
#define cpu_to_le32(x) ((uint32_t)(x))
|
||||
#define cpu_to_le64(x) ((uint64_t)(x))
|
||||
#define cpu_to_be16(x) swab16(x)
|
||||
#define cpu_to_be32(x) swab32(x)
|
||||
#define cpu_to_be64(x) swab64(x)
|
||||
|
||||
#define le16_to_cpu(x) ((uint16_t)(x))
|
||||
#define le32_to_cpu(x) ((uint32_t)(x))
|
||||
#define le64_to_cpu(x) ((uint64_t)(x))
|
||||
#define be16_to_cpu(x) swab16(x)
|
||||
#define be32_to_cpu(x) swab32(x)
|
||||
#define be64_to_cpu(x) swab64(x)
|
||||
|
||||
#endif /* WORDS_BIGENDIAN */
|
||||
|
||||
#endif /* BITOPS_H */
|
||||
@@ -1,16 +0,0 @@
|
||||
#ifndef BLOCKDEV_H
|
||||
#define BLOCKDEV_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
#include <unistd.h>
|
||||
#include <asm/types.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/mount.h>
|
||||
|
||||
#if defined(__linux__) && defined(_IOR) && !defined(BLKGETSIZE64)
|
||||
# define BLKGETSIZE64 _IOR(0x12, 114, size_t)
|
||||
#endif
|
||||
|
||||
#endif /* BLOCKDEV_H */
|
||||
102
lib/crypt_plain.c
Normal file
102
lib/crypt_plain.c
Normal file
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* cryptsetup plain device helper functions
|
||||
*
|
||||
* Copyright (C) 2004, Christophe Saout <christophe@saout.de>
|
||||
* Copyright (C) 2010-2011 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
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "libcryptsetup.h"
|
||||
#include "internal.h"
|
||||
|
||||
static int hash(const char *hash_name, size_t key_size, char *key,
|
||||
size_t passphrase_size, const char *passphrase)
|
||||
{
|
||||
struct crypt_hash *md = NULL;
|
||||
size_t len;
|
||||
int round, i, r = 0;
|
||||
|
||||
if (crypt_hash_init(&md, hash_name))
|
||||
return -ENOENT;
|
||||
|
||||
len = crypt_hash_size(hash_name);
|
||||
|
||||
for(round = 0; key_size && !r; round++) {
|
||||
/* hack from hashalot to avoid null bytes in key */
|
||||
for(i = 0; i < round; i++)
|
||||
if (crypt_hash_write(md, "A", 1))
|
||||
r = 1;
|
||||
|
||||
if (crypt_hash_write(md, passphrase, passphrase_size))
|
||||
r = 1;
|
||||
|
||||
if (len > key_size)
|
||||
len = key_size;
|
||||
|
||||
if (crypt_hash_final(md, key, len))
|
||||
r = 1;
|
||||
|
||||
key += len;
|
||||
key_size -= len;
|
||||
}
|
||||
|
||||
crypt_hash_destroy(md);
|
||||
return r;
|
||||
}
|
||||
|
||||
#define PLAIN_HASH_LEN_MAX 256
|
||||
|
||||
int crypt_plain_hash(struct crypt_device *ctx __attribute__((unused)),
|
||||
const char *hash_name,
|
||||
char *key, size_t key_size,
|
||||
const char *passphrase, size_t passphrase_size)
|
||||
{
|
||||
char hash_name_buf[PLAIN_HASH_LEN_MAX], *s;
|
||||
size_t hash_size, pad_size;
|
||||
int r;
|
||||
|
||||
log_dbg("Plain: hashing passphrase using %s.", hash_name);
|
||||
|
||||
if (strlen(hash_name) >= PLAIN_HASH_LEN_MAX)
|
||||
return -EINVAL;
|
||||
strncpy(hash_name_buf, hash_name, PLAIN_HASH_LEN_MAX);
|
||||
hash_name_buf[PLAIN_HASH_LEN_MAX - 1] = '\0';
|
||||
|
||||
/* hash[:hash_length] */
|
||||
if ((s = strchr(hash_name_buf, ':'))) {
|
||||
*s = '\0';
|
||||
hash_size = atoi(++s);
|
||||
if (hash_size > key_size) {
|
||||
log_dbg("Hash length %zd > key length %zd",
|
||||
hash_size, key_size);
|
||||
return -EINVAL;
|
||||
}
|
||||
pad_size = key_size - hash_size;
|
||||
} else {
|
||||
hash_size = key_size;
|
||||
pad_size = 0;
|
||||
}
|
||||
|
||||
r = hash(hash_name_buf, hash_size, key, passphrase_size, passphrase);
|
||||
|
||||
if (r == 0 && pad_size)
|
||||
memset(key + hash_size, 0, pad_size);
|
||||
|
||||
return r;
|
||||
}
|
||||
25
lib/crypto_backend/Makefile.am
Normal file
25
lib/crypto_backend/Makefile.am
Normal file
@@ -0,0 +1,25 @@
|
||||
moduledir = $(libdir)/cryptsetup
|
||||
|
||||
noinst_LTLIBRARIES = libcrypto_backend.la
|
||||
|
||||
libcrypto_backend_la_CFLAGS = -Wall @CRYPTO_CFLAGS@
|
||||
|
||||
libcrypto_backend_la_SOURCES = crypto_backend.h
|
||||
|
||||
if CRYPTO_BACKEND_GCRYPT
|
||||
libcrypto_backend_la_SOURCES += crypto_gcrypt.c
|
||||
endif
|
||||
if CRYPTO_BACKEND_OPENSSL
|
||||
libcrypto_backend_la_SOURCES += crypto_openssl.c
|
||||
endif
|
||||
if CRYPTO_BACKEND_NSS
|
||||
libcrypto_backend_la_SOURCES += crypto_nss.c
|
||||
endif
|
||||
if CRYPTO_BACKEND_KERNEL
|
||||
libcrypto_backend_la_SOURCES += crypto_kernel.c
|
||||
endif
|
||||
if CRYPTO_BACKEND_NETTLE
|
||||
libcrypto_backend_la_SOURCES += crypto_nettle.c
|
||||
endif
|
||||
|
||||
INCLUDES = -D_GNU_SOURCE -I$(top_srcdir)/lib
|
||||
55
lib/crypto_backend/crypto_backend.h
Normal file
55
lib/crypto_backend/crypto_backend.h
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* crypto backend implementation
|
||||
*
|
||||
* Copyright (C) 2010-2012, 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
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#ifndef _CRYPTO_BACKEND_H
|
||||
#define _CRYPTO_BACKEND_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "config.h"
|
||||
|
||||
struct crypt_device;
|
||||
struct crypt_hash;
|
||||
struct crypt_hmac;
|
||||
|
||||
int crypt_backend_init(struct crypt_device *ctx);
|
||||
|
||||
#define CRYPT_BACKEND_KERNEL (1 << 0) /* Crypto uses kernel part, for benchmark */
|
||||
|
||||
uint32_t crypt_backend_flags(void);
|
||||
const char *crypt_backend_version(void);
|
||||
|
||||
/* HASH */
|
||||
int crypt_hash_size(const char *name);
|
||||
int crypt_hash_init(struct crypt_hash **ctx, const char *name);
|
||||
int crypt_hash_write(struct crypt_hash *ctx, const char *buffer, size_t length);
|
||||
int crypt_hash_final(struct crypt_hash *ctx, char *buffer, size_t length);
|
||||
int crypt_hash_destroy(struct crypt_hash *ctx);
|
||||
|
||||
/* HMAC */
|
||||
int crypt_hmac_size(const char *name);
|
||||
int crypt_hmac_init(struct crypt_hmac **ctx, const char *name,
|
||||
const void *buffer, size_t length);
|
||||
int crypt_hmac_write(struct crypt_hmac *ctx, const char *buffer, size_t length);
|
||||
int crypt_hmac_final(struct crypt_hmac *ctx, char *buffer, size_t length);
|
||||
int crypt_hmac_destroy(struct crypt_hmac *ctx);
|
||||
|
||||
/* RNG (if fips paramater set, must provide FIPS compliance) */
|
||||
enum { CRYPT_RND_NORMAL = 0, CRYPT_RND_KEY = 1, CRYPT_RND_SALT = 2 };
|
||||
int crypt_backend_rng(char *buffer, size_t length, int quality, int fips);
|
||||
|
||||
#endif /* _CRYPTO_BACKEND_H */
|
||||
253
lib/crypto_backend/crypto_gcrypt.c
Normal file
253
lib/crypto_backend/crypto_gcrypt.c
Normal file
@@ -0,0 +1,253 @@
|
||||
/*
|
||||
* GCRYPT crypto backend implementation
|
||||
*
|
||||
* Copyright (C) 2010-2012, 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
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <gcrypt.h>
|
||||
#include "crypto_backend.h"
|
||||
|
||||
static int crypto_backend_initialised = 0;
|
||||
static int crypto_backend_secmem = 1;
|
||||
static char version[64];
|
||||
|
||||
struct crypt_hash {
|
||||
gcry_md_hd_t hd;
|
||||
int hash_id;
|
||||
int hash_len;
|
||||
};
|
||||
|
||||
struct crypt_hmac {
|
||||
gcry_md_hd_t hd;
|
||||
int hash_id;
|
||||
int hash_len;
|
||||
};
|
||||
|
||||
int crypt_backend_init(struct crypt_device *ctx)
|
||||
{
|
||||
if (crypto_backend_initialised)
|
||||
return 0;
|
||||
|
||||
if (!gcry_control (GCRYCTL_INITIALIZATION_FINISHED_P)) {
|
||||
if (!gcry_check_version (GCRYPT_REQ_VERSION)) {
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
/* FIXME: If gcrypt compiled to support POSIX 1003.1e capabilities,
|
||||
* it drops all privileges during secure memory initialisation.
|
||||
* For now, the only workaround is to disable secure memory in gcrypt.
|
||||
* cryptsetup always need at least cap_sys_admin privilege for dm-ioctl
|
||||
* and it locks its memory space anyway.
|
||||
*/
|
||||
#if 0
|
||||
gcry_control (GCRYCTL_DISABLE_SECMEM);
|
||||
crypto_backend_secmem = 0;
|
||||
#else
|
||||
|
||||
gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
|
||||
gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
|
||||
gcry_control (GCRYCTL_RESUME_SECMEM_WARN);
|
||||
#endif
|
||||
gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
|
||||
}
|
||||
|
||||
snprintf(version, 64, "gcrypt %s%s",
|
||||
gcry_check_version(NULL),
|
||||
crypto_backend_secmem ? "" : ", secmem disabled");
|
||||
crypto_backend_initialised = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *crypt_backend_version(void)
|
||||
{
|
||||
return crypto_backend_initialised ? version : "";
|
||||
}
|
||||
|
||||
uint32_t crypt_backend_flags(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* HASH */
|
||||
int crypt_hash_size(const char *name)
|
||||
{
|
||||
int hash_id;
|
||||
|
||||
assert(crypto_backend_initialised);
|
||||
|
||||
hash_id = gcry_md_map_name(name);
|
||||
if (!hash_id)
|
||||
return -EINVAL;
|
||||
|
||||
return gcry_md_get_algo_dlen(hash_id);
|
||||
}
|
||||
|
||||
int crypt_hash_init(struct crypt_hash **ctx, const char *name)
|
||||
{
|
||||
struct crypt_hash *h;
|
||||
|
||||
assert(crypto_backend_initialised);
|
||||
|
||||
h = malloc(sizeof(*h));
|
||||
if (!h)
|
||||
return -ENOMEM;
|
||||
|
||||
h->hash_id = gcry_md_map_name(name);
|
||||
if (!h->hash_id) {
|
||||
free(h);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (gcry_md_open(&h->hd, h->hash_id, 0)) {
|
||||
free(h);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
h->hash_len = gcry_md_get_algo_dlen(h->hash_id);
|
||||
*ctx = h;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void crypt_hash_restart(struct crypt_hash *ctx)
|
||||
{
|
||||
gcry_md_reset(ctx->hd);
|
||||
}
|
||||
|
||||
int crypt_hash_write(struct crypt_hash *ctx, const char *buffer, size_t length)
|
||||
{
|
||||
gcry_md_write(ctx->hd, buffer, length);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypt_hash_final(struct crypt_hash *ctx, char *buffer, size_t length)
|
||||
{
|
||||
unsigned char *hash;
|
||||
|
||||
if (length > (size_t)ctx->hash_len)
|
||||
return -EINVAL;
|
||||
|
||||
hash = gcry_md_read(ctx->hd, ctx->hash_id);
|
||||
if (!hash)
|
||||
return -EINVAL;
|
||||
|
||||
memcpy(buffer, hash, length);
|
||||
crypt_hash_restart(ctx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypt_hash_destroy(struct crypt_hash *ctx)
|
||||
{
|
||||
gcry_md_close(ctx->hd);
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
free(ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 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 *buffer, size_t length)
|
||||
{
|
||||
struct crypt_hmac *h;
|
||||
|
||||
assert(crypto_backend_initialised);
|
||||
|
||||
h = malloc(sizeof(*h));
|
||||
if (!h)
|
||||
return -ENOMEM;
|
||||
|
||||
h->hash_id = gcry_md_map_name(name);
|
||||
if (!h->hash_id) {
|
||||
free(h);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (gcry_md_open(&h->hd, h->hash_id, GCRY_MD_FLAG_HMAC)) {
|
||||
free(h);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (gcry_md_setkey(h->hd, buffer, length)) {
|
||||
gcry_md_close(h->hd);
|
||||
free(h);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
h->hash_len = gcry_md_get_algo_dlen(h->hash_id);
|
||||
*ctx = h;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void crypt_hmac_restart(struct crypt_hmac *ctx)
|
||||
{
|
||||
gcry_md_reset(ctx->hd);
|
||||
}
|
||||
|
||||
int crypt_hmac_write(struct crypt_hmac *ctx, const char *buffer, size_t length)
|
||||
{
|
||||
gcry_md_write(ctx->hd, buffer, length);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypt_hmac_final(struct crypt_hmac *ctx, char *buffer, size_t length)
|
||||
{
|
||||
unsigned char *hash;
|
||||
|
||||
if (length > (size_t)ctx->hash_len)
|
||||
return -EINVAL;
|
||||
|
||||
hash = gcry_md_read(ctx->hd, ctx->hash_id);
|
||||
if (!hash)
|
||||
return -EINVAL;
|
||||
|
||||
memcpy(buffer, hash, length);
|
||||
crypt_hmac_restart(ctx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypt_hmac_destroy(struct crypt_hmac *ctx)
|
||||
{
|
||||
gcry_md_close(ctx->hd);
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
free(ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* RNG */
|
||||
int crypt_backend_rng(char *buffer, size_t length, int quality, int fips)
|
||||
{
|
||||
switch(quality) {
|
||||
case CRYPT_RND_NORMAL:
|
||||
gcry_randomize(buffer, length, GCRY_STRONG_RANDOM);
|
||||
break;
|
||||
case CRYPT_RND_SALT:
|
||||
case CRYPT_RND_KEY:
|
||||
default:
|
||||
gcry_randomize(buffer, length, GCRY_VERY_STRONG_RANDOM);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
304
lib/crypto_backend/crypto_kernel.c
Normal file
304
lib/crypto_backend/crypto_kernel.c
Normal file
@@ -0,0 +1,304 @@
|
||||
/*
|
||||
* Linux kernel userspace API crypto backend implementation
|
||||
*
|
||||
* Copyright (C) 2010-2012, 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
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/utsname.h>
|
||||
#include <linux/if_alg.h>
|
||||
#include "crypto_backend.h"
|
||||
|
||||
/* FIXME: remove later */
|
||||
#ifndef AF_ALG
|
||||
#define AF_ALG 38
|
||||
#endif
|
||||
#ifndef SOL_ALG
|
||||
#define SOL_ALG 279
|
||||
#endif
|
||||
|
||||
static int crypto_backend_initialised = 0;
|
||||
static char version[64];
|
||||
|
||||
struct hash_alg {
|
||||
const char *name;
|
||||
const char *kernel_name;
|
||||
int length;
|
||||
};
|
||||
|
||||
static struct hash_alg hash_algs[] = {
|
||||
{ "sha1", "sha1", 20 },
|
||||
{ "sha256", "sha256", 32 },
|
||||
{ "sha512", "sha512", 64 },
|
||||
{ "ripemd160", "rmd160", 20 },
|
||||
{ "whirlpool", "wp512", 64 },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
struct crypt_hash {
|
||||
int tfmfd;
|
||||
int opfd;
|
||||
int hash_len;
|
||||
};
|
||||
|
||||
struct crypt_hmac {
|
||||
int tfmfd;
|
||||
int opfd;
|
||||
int hash_len;
|
||||
};
|
||||
|
||||
static int _socket_init(struct sockaddr_alg *sa, int *tfmfd, int *opfd)
|
||||
{
|
||||
*tfmfd = socket(AF_ALG, SOCK_SEQPACKET, 0);
|
||||
if (*tfmfd == -1)
|
||||
goto bad;
|
||||
|
||||
if (bind(*tfmfd, (struct sockaddr *)sa, sizeof(*sa)) == -1)
|
||||
goto bad;
|
||||
|
||||
*opfd = accept(*tfmfd, NULL, 0);
|
||||
if (*opfd == -1)
|
||||
goto bad;
|
||||
|
||||
return 0;
|
||||
bad:
|
||||
if (*tfmfd != -1) {
|
||||
close(*tfmfd);
|
||||
*tfmfd = -1;
|
||||
}
|
||||
if (*opfd != -1) {
|
||||
close(*opfd);
|
||||
*opfd = -1;
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
int crypt_backend_init(struct crypt_device *ctx)
|
||||
{
|
||||
struct utsname uts;
|
||||
struct sockaddr_alg sa = {
|
||||
.salg_family = AF_ALG,
|
||||
.salg_type = "hash",
|
||||
.salg_name = "sha1",
|
||||
};
|
||||
int tfmfd = -1, opfd = -1;
|
||||
|
||||
if (crypto_backend_initialised)
|
||||
return 0;
|
||||
|
||||
if (uname(&uts) == -1 || strcmp(uts.sysname, "Linux"))
|
||||
return -EINVAL;
|
||||
|
||||
if (_socket_init(&sa, &tfmfd, &opfd) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
close(tfmfd);
|
||||
close(opfd);
|
||||
|
||||
snprintf(version, sizeof(version), "%s %s kernel cryptoAPI",
|
||||
uts.sysname, uts.release);
|
||||
|
||||
crypto_backend_initialised = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t crypt_backend_flags(void)
|
||||
{
|
||||
return CRYPT_BACKEND_KERNEL;
|
||||
}
|
||||
|
||||
const char *crypt_backend_version(void)
|
||||
{
|
||||
return crypto_backend_initialised ? version : "";
|
||||
}
|
||||
|
||||
static struct hash_alg *_get_alg(const char *name)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
while (name && hash_algs[i].name) {
|
||||
if (!strcmp(name, hash_algs[i].name))
|
||||
return &hash_algs[i];
|
||||
i++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* HASH */
|
||||
int crypt_hash_size(const char *name)
|
||||
{
|
||||
struct hash_alg *ha = _get_alg(name);
|
||||
|
||||
return ha ? ha->length : -EINVAL;
|
||||
}
|
||||
|
||||
int crypt_hash_init(struct crypt_hash **ctx, const char *name)
|
||||
{
|
||||
struct crypt_hash *h;
|
||||
struct hash_alg *ha;
|
||||
struct sockaddr_alg sa = {
|
||||
.salg_family = AF_ALG,
|
||||
.salg_type = "hash",
|
||||
};
|
||||
|
||||
h = malloc(sizeof(*h));
|
||||
if (!h)
|
||||
return -ENOMEM;
|
||||
|
||||
ha = _get_alg(name);
|
||||
if (!ha) {
|
||||
free(h);
|
||||
return -EINVAL;
|
||||
}
|
||||
h->hash_len = ha->length;
|
||||
|
||||
strncpy((char *)sa.salg_name, ha->kernel_name, sizeof(sa.salg_name));
|
||||
|
||||
if (_socket_init(&sa, &h->tfmfd, &h->opfd) < 0) {
|
||||
free(h);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
*ctx = h;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypt_hash_write(struct crypt_hash *ctx, const char *buffer, size_t length)
|
||||
{
|
||||
ssize_t r;
|
||||
|
||||
r = send(ctx->opfd, buffer, length, MSG_MORE);
|
||||
if (r < 0 || (size_t)r < length)
|
||||
return -EIO;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypt_hash_final(struct crypt_hash *ctx, char *buffer, size_t length)
|
||||
{
|
||||
ssize_t r;
|
||||
|
||||
if (length > (size_t)ctx->hash_len)
|
||||
return -EINVAL;
|
||||
|
||||
r = read(ctx->opfd, buffer, length);
|
||||
if (r < 0)
|
||||
return -EIO;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypt_hash_destroy(struct crypt_hash *ctx)
|
||||
{
|
||||
if (ctx->tfmfd != -1)
|
||||
close(ctx->tfmfd);
|
||||
if (ctx->opfd != -1)
|
||||
close(ctx->opfd);
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
free(ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 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 *buffer, size_t length)
|
||||
{
|
||||
struct crypt_hmac *h;
|
||||
struct hash_alg *ha;
|
||||
struct sockaddr_alg sa = {
|
||||
.salg_family = AF_ALG,
|
||||
.salg_type = "hash",
|
||||
};
|
||||
|
||||
h = malloc(sizeof(*h));
|
||||
if (!h)
|
||||
return -ENOMEM;
|
||||
|
||||
ha = _get_alg(name);
|
||||
if (!ha) {
|
||||
free(h);
|
||||
return -EINVAL;
|
||||
}
|
||||
h->hash_len = ha->length;
|
||||
|
||||
snprintf((char *)sa.salg_name, sizeof(sa.salg_name),
|
||||
"hmac(%s)", ha->kernel_name);
|
||||
|
||||
if (_socket_init(&sa, &h->tfmfd, &h->opfd) < 0) {
|
||||
free(h);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (setsockopt(h->tfmfd, SOL_ALG, ALG_SET_KEY, buffer, length) == -1) {
|
||||
crypt_hmac_destroy(h);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
*ctx = h;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypt_hmac_write(struct crypt_hmac *ctx, const char *buffer, size_t length)
|
||||
{
|
||||
ssize_t r;
|
||||
|
||||
r = send(ctx->opfd, buffer, length, MSG_MORE);
|
||||
if (r < 0 || (size_t)r < length)
|
||||
return -EIO;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypt_hmac_final(struct crypt_hmac *ctx, char *buffer, size_t length)
|
||||
{
|
||||
ssize_t r;
|
||||
|
||||
if (length > (size_t)ctx->hash_len)
|
||||
return -EINVAL;
|
||||
|
||||
r = read(ctx->opfd, buffer, length);
|
||||
if (r < 0)
|
||||
return -EIO;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypt_hmac_destroy(struct crypt_hmac *ctx)
|
||||
{
|
||||
if (ctx->tfmfd != -1)
|
||||
close(ctx->tfmfd);
|
||||
if (ctx->opfd != -1)
|
||||
close(ctx->opfd);
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
free(ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* RNG - N/A */
|
||||
int crypt_backend_rng(char *buffer, size_t length, int quality, int fips)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
276
lib/crypto_backend/crypto_nettle.c
Normal file
276
lib/crypto_backend/crypto_nettle.c
Normal file
@@ -0,0 +1,276 @@
|
||||
/*
|
||||
* Nettle crypto backend implementation
|
||||
*
|
||||
* Copyright (C) 2011-2012 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
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <nettle/sha.h>
|
||||
#include <nettle/hmac.h>
|
||||
#include "crypto_backend.h"
|
||||
|
||||
static char *version = "Nettle";
|
||||
|
||||
typedef void (*init_func) (void *);
|
||||
typedef void (*update_func) (void *, unsigned, const uint8_t *);
|
||||
typedef void (*digest_func) (void *, unsigned, uint8_t *);
|
||||
typedef void (*set_key_func) (void *, unsigned, const uint8_t *);
|
||||
|
||||
struct hash_alg {
|
||||
const char *name;
|
||||
int length;
|
||||
init_func init;
|
||||
update_func update;
|
||||
digest_func digest;
|
||||
update_func hmac_update;
|
||||
digest_func hmac_digest;
|
||||
set_key_func hmac_set_key;
|
||||
};
|
||||
|
||||
static struct hash_alg hash_algs[] = {
|
||||
{ "sha1", SHA1_DIGEST_SIZE,
|
||||
(init_func) sha1_init,
|
||||
(update_func) sha1_update,
|
||||
(digest_func) sha1_digest,
|
||||
(update_func) hmac_sha1_update,
|
||||
(digest_func) hmac_sha1_digest,
|
||||
(set_key_func) hmac_sha1_set_key,
|
||||
},
|
||||
{ "sha224", SHA224_DIGEST_SIZE,
|
||||
(init_func) sha224_init,
|
||||
(update_func) sha224_update,
|
||||
(digest_func) sha224_digest,
|
||||
(update_func) hmac_sha224_update,
|
||||
(digest_func) hmac_sha224_digest,
|
||||
(set_key_func) hmac_sha224_set_key,
|
||||
},
|
||||
{ "sha256", SHA256_DIGEST_SIZE,
|
||||
(init_func) sha256_init,
|
||||
(update_func) sha256_update,
|
||||
(digest_func) sha256_digest,
|
||||
(update_func) hmac_sha256_update,
|
||||
(digest_func) hmac_sha256_digest,
|
||||
(set_key_func) hmac_sha256_set_key,
|
||||
},
|
||||
{ "sha384", SHA384_DIGEST_SIZE,
|
||||
(init_func) sha384_init,
|
||||
(update_func) sha384_update,
|
||||
(digest_func) sha384_digest,
|
||||
(update_func) hmac_sha384_update,
|
||||
(digest_func) hmac_sha384_digest,
|
||||
(set_key_func) hmac_sha384_set_key,
|
||||
},
|
||||
{ "sha512", SHA512_DIGEST_SIZE,
|
||||
(init_func) sha512_init,
|
||||
(update_func) sha512_update,
|
||||
(digest_func) sha512_digest,
|
||||
(update_func) hmac_sha512_update,
|
||||
(digest_func) hmac_sha512_digest,
|
||||
(set_key_func) hmac_sha512_set_key,
|
||||
},
|
||||
{ "ripemd160", RIPEMD160_DIGEST_SIZE,
|
||||
(init_func) ripemd160_init,
|
||||
(update_func) ripemd160_update,
|
||||
(digest_func) ripemd160_digest,
|
||||
(update_func) hmac_ripemd160_update,
|
||||
(digest_func) hmac_ripemd160_digest,
|
||||
(set_key_func) hmac_ripemd160_set_key,
|
||||
},
|
||||
{ NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, }
|
||||
};
|
||||
|
||||
struct crypt_hash {
|
||||
const struct hash_alg *hash;
|
||||
union {
|
||||
struct sha1_ctx sha1;
|
||||
struct sha224_ctx sha224;
|
||||
struct sha256_ctx sha256;
|
||||
struct sha384_ctx sha384;
|
||||
struct sha512_ctx sha512;
|
||||
} nettle_ctx;
|
||||
};
|
||||
|
||||
struct crypt_hmac {
|
||||
const struct hash_alg *hash;
|
||||
union {
|
||||
struct hmac_sha1_ctx sha1;
|
||||
struct hmac_sha224_ctx sha224;
|
||||
struct hmac_sha256_ctx sha256;
|
||||
struct hmac_sha384_ctx sha384;
|
||||
struct hmac_sha512_ctx sha512;
|
||||
} nettle_ctx;
|
||||
size_t key_length;
|
||||
uint8_t *key;
|
||||
};
|
||||
|
||||
uint32_t crypt_backend_flags(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct hash_alg *_get_alg(const char *name)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
while (name && hash_algs[i].name) {
|
||||
if (!strcmp(name, hash_algs[i].name))
|
||||
return &hash_algs[i];
|
||||
i++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int crypt_backend_init(struct crypt_device *ctx)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *crypt_backend_version(void)
|
||||
{
|
||||
return version;
|
||||
}
|
||||
|
||||
/* HASH */
|
||||
int crypt_hash_size(const char *name)
|
||||
{
|
||||
struct hash_alg *ha = _get_alg(name);
|
||||
|
||||
return ha ? ha->length : -EINVAL;
|
||||
}
|
||||
|
||||
int crypt_hash_init(struct crypt_hash **ctx, const char *name)
|
||||
{
|
||||
struct crypt_hash *h;
|
||||
|
||||
h = malloc(sizeof(*h));
|
||||
if (!h)
|
||||
return -ENOMEM;
|
||||
|
||||
h->hash = _get_alg(name);
|
||||
if (!h->hash) {
|
||||
free(h);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
h->hash->init(&h->nettle_ctx);
|
||||
|
||||
*ctx = h;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void crypt_hash_restart(struct crypt_hash *ctx)
|
||||
{
|
||||
ctx->hash->init(&ctx->nettle_ctx);
|
||||
}
|
||||
|
||||
int crypt_hash_write(struct crypt_hash *ctx, const char *buffer, size_t length)
|
||||
{
|
||||
ctx->hash->update(&ctx->nettle_ctx, length, (const uint8_t*)buffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypt_hash_final(struct crypt_hash *ctx, char *buffer, size_t length)
|
||||
{
|
||||
if (length > (size_t)ctx->hash->length)
|
||||
return -EINVAL;
|
||||
|
||||
ctx->hash->digest(&ctx->nettle_ctx, length, (uint8_t *)buffer);
|
||||
crypt_hash_restart(ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypt_hash_destroy(struct crypt_hash *ctx)
|
||||
{
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
free(ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 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 *buffer, size_t length)
|
||||
{
|
||||
struct crypt_hmac *h;
|
||||
|
||||
h = malloc(sizeof(*h));
|
||||
if (!h)
|
||||
return -ENOMEM;
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
|
||||
|
||||
h->hash = _get_alg(name);
|
||||
if (!h->hash)
|
||||
goto bad;
|
||||
|
||||
h->key = malloc(length);
|
||||
if (!h->key)
|
||||
goto bad;
|
||||
|
||||
memcpy(h->key, buffer, length);
|
||||
h->key_length = length;
|
||||
|
||||
h->hash->init(&h->nettle_ctx);
|
||||
h->hash->hmac_set_key(&h->nettle_ctx, h->key_length, h->key);
|
||||
|
||||
*ctx = h;
|
||||
return 0;
|
||||
bad:
|
||||
free(h);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static void crypt_hmac_restart(struct crypt_hmac *ctx)
|
||||
{
|
||||
ctx->hash->hmac_set_key(&ctx->nettle_ctx, ctx->key_length, ctx->key);
|
||||
}
|
||||
|
||||
int crypt_hmac_write(struct crypt_hmac *ctx, const char *buffer, size_t length)
|
||||
{
|
||||
ctx->hash->hmac_update(&ctx->nettle_ctx, length, (const uint8_t *)buffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypt_hmac_final(struct crypt_hmac *ctx, char *buffer, size_t length)
|
||||
{
|
||||
if (length > (size_t)ctx->hash->length)
|
||||
return -EINVAL;
|
||||
|
||||
ctx->hash->hmac_digest(&ctx->nettle_ctx, length, (uint8_t *)buffer);
|
||||
crypt_hmac_restart(ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypt_hmac_destroy(struct crypt_hmac *ctx)
|
||||
{
|
||||
memset(ctx->key, 0, ctx->key_length);
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
free(ctx->key);
|
||||
free(ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* RNG - N/A */
|
||||
int crypt_backend_rng(char *buffer, size_t length, int quality, int fips)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
300
lib/crypto_backend/crypto_nss.c
Normal file
300
lib/crypto_backend/crypto_nss.c
Normal file
@@ -0,0 +1,300 @@
|
||||
/*
|
||||
* NSS crypto backend implementation
|
||||
*
|
||||
* Copyright (C) 2010-2012, 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
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <nss.h>
|
||||
#include <pk11pub.h>
|
||||
#include "crypto_backend.h"
|
||||
|
||||
#define CONST_CAST(x) (x)(uintptr_t)
|
||||
|
||||
static int crypto_backend_initialised = 0;
|
||||
static char version[64];
|
||||
|
||||
struct hash_alg {
|
||||
const char *name;
|
||||
SECOidTag oid;
|
||||
CK_MECHANISM_TYPE ck_type;
|
||||
int length;
|
||||
};
|
||||
|
||||
static struct hash_alg hash_algs[] = {
|
||||
{ "sha1", SEC_OID_SHA1, CKM_SHA_1_HMAC, 20 },
|
||||
{ "sha256", SEC_OID_SHA256, CKM_SHA256_HMAC, 32 },
|
||||
{ "sha384", SEC_OID_SHA384, CKM_SHA384_HMAC, 48 },
|
||||
{ "sha512", SEC_OID_SHA512, CKM_SHA512_HMAC, 64 },
|
||||
// { "ripemd160", SEC_OID_RIPEMD160, CKM_RIPEMD160_HMAC, 20 },
|
||||
{ NULL, 0, 0, 0 }
|
||||
};
|
||||
|
||||
struct crypt_hash {
|
||||
PK11Context *md;
|
||||
const struct hash_alg *hash;
|
||||
};
|
||||
|
||||
struct crypt_hmac {
|
||||
PK11Context *md;
|
||||
PK11SymKey *key;
|
||||
PK11SlotInfo *slot;
|
||||
const struct hash_alg *hash;
|
||||
};
|
||||
|
||||
static struct hash_alg *_get_alg(const char *name)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
while (name && hash_algs[i].name) {
|
||||
if (!strcmp(name, hash_algs[i].name))
|
||||
return &hash_algs[i];
|
||||
i++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int crypt_backend_init(struct crypt_device *ctx)
|
||||
{
|
||||
if (crypto_backend_initialised)
|
||||
return 0;
|
||||
|
||||
if (NSS_NoDB_Init(".") != SECSuccess)
|
||||
return -EINVAL;
|
||||
|
||||
#if HAVE_DECL_NSS_GETVERSION
|
||||
snprintf(version, 64, "NSS %s", NSS_GetVersion());
|
||||
#else
|
||||
snprintf(version, 64, "NSS");
|
||||
#endif
|
||||
crypto_backend_initialised = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t crypt_backend_flags(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *crypt_backend_version(void)
|
||||
{
|
||||
return crypto_backend_initialised ? version : "";
|
||||
}
|
||||
|
||||
/* HASH */
|
||||
int crypt_hash_size(const char *name)
|
||||
{
|
||||
struct hash_alg *ha = _get_alg(name);
|
||||
|
||||
return ha ? ha->length : -EINVAL;
|
||||
}
|
||||
|
||||
int crypt_hash_init(struct crypt_hash **ctx, const char *name)
|
||||
{
|
||||
struct crypt_hash *h;
|
||||
|
||||
h = malloc(sizeof(*h));
|
||||
if (!h)
|
||||
return -ENOMEM;
|
||||
|
||||
h->hash = _get_alg(name);
|
||||
if (!h->hash) {
|
||||
free(h);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
h->md = PK11_CreateDigestContext(h->hash->oid);
|
||||
if (!h->md) {
|
||||
free(h);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (PK11_DigestBegin(h->md) != SECSuccess) {
|
||||
PK11_DestroyContext(h->md, PR_TRUE);
|
||||
free(h);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
*ctx = h;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int crypt_hash_restart(struct crypt_hash *ctx)
|
||||
{
|
||||
if (PK11_DigestBegin(ctx->md) != SECSuccess)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypt_hash_write(struct crypt_hash *ctx, const char *buffer, size_t length)
|
||||
{
|
||||
if (PK11_DigestOp(ctx->md, CONST_CAST(unsigned char *)buffer, length) != SECSuccess)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypt_hash_final(struct crypt_hash *ctx, char *buffer, size_t length)
|
||||
{
|
||||
unsigned char tmp[64];
|
||||
unsigned int tmp_len;
|
||||
|
||||
if (length > (size_t)ctx->hash->length)
|
||||
return -EINVAL;
|
||||
|
||||
if (PK11_DigestFinal(ctx->md, tmp, &tmp_len, length) != SECSuccess)
|
||||
return -EINVAL;
|
||||
|
||||
memcpy(buffer, tmp, length);
|
||||
memset(tmp, 0, sizeof(tmp));
|
||||
|
||||
if (tmp_len < length)
|
||||
return -EINVAL;
|
||||
|
||||
if (crypt_hash_restart(ctx))
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypt_hash_destroy(struct crypt_hash *ctx)
|
||||
{
|
||||
PK11_DestroyContext(ctx->md, PR_TRUE);
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
free(ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 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 *buffer, size_t length)
|
||||
{
|
||||
struct crypt_hmac *h;
|
||||
SECItem keyItem;
|
||||
SECItem noParams;
|
||||
|
||||
keyItem.type = siBuffer;
|
||||
keyItem.data = CONST_CAST(unsigned char *)buffer;
|
||||
keyItem.len = (int)length;
|
||||
|
||||
noParams.type = siBuffer;
|
||||
noParams.data = 0;
|
||||
noParams.len = 0;
|
||||
|
||||
h = malloc(sizeof(*h));
|
||||
if (!h)
|
||||
return -ENOMEM;
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
|
||||
|
||||
h->hash = _get_alg(name);
|
||||
if (!h->hash)
|
||||
goto bad;
|
||||
|
||||
h->slot = PK11_GetInternalKeySlot();
|
||||
if (!h->slot)
|
||||
goto bad;
|
||||
|
||||
h->key = PK11_ImportSymKey(h->slot, h->hash->ck_type, PK11_OriginUnwrap,
|
||||
CKA_SIGN, &keyItem, NULL);
|
||||
if (!h->key)
|
||||
goto bad;
|
||||
|
||||
h->md = PK11_CreateContextBySymKey(h->hash->ck_type, CKA_SIGN, h->key,
|
||||
&noParams);
|
||||
if (!h->md)
|
||||
goto bad;
|
||||
|
||||
if (PK11_DigestBegin(h->md) != SECSuccess)
|
||||
goto bad;
|
||||
|
||||
*ctx = h;
|
||||
return 0;
|
||||
bad:
|
||||
crypt_hmac_destroy(h);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int crypt_hmac_restart(struct crypt_hmac *ctx)
|
||||
{
|
||||
if (PK11_DigestBegin(ctx->md) != SECSuccess)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypt_hmac_write(struct crypt_hmac *ctx, const char *buffer, size_t length)
|
||||
{
|
||||
if (PK11_DigestOp(ctx->md, CONST_CAST(unsigned char *)buffer, length) != SECSuccess)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypt_hmac_final(struct crypt_hmac *ctx, char *buffer, size_t length)
|
||||
{
|
||||
unsigned char tmp[64];
|
||||
unsigned int tmp_len;
|
||||
|
||||
if (length > (size_t)ctx->hash->length)
|
||||
return -EINVAL;
|
||||
|
||||
if (PK11_DigestFinal(ctx->md, tmp, &tmp_len, length) != SECSuccess)
|
||||
return -EINVAL;
|
||||
|
||||
memcpy(buffer, tmp, length);
|
||||
memset(tmp, 0, sizeof(tmp));
|
||||
|
||||
if (tmp_len < length)
|
||||
return -EINVAL;
|
||||
|
||||
if (crypt_hmac_restart(ctx))
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypt_hmac_destroy(struct crypt_hmac *ctx)
|
||||
{
|
||||
if (ctx->key)
|
||||
PK11_FreeSymKey(ctx->key);
|
||||
if (ctx->slot)
|
||||
PK11_FreeSlot(ctx->slot);
|
||||
if (ctx->md)
|
||||
PK11_DestroyContext(ctx->md, PR_TRUE);
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
free(ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* RNG */
|
||||
int crypt_backend_rng(char *buffer, size_t length, int quality, int fips)
|
||||
{
|
||||
if (fips)
|
||||
return -EINVAL;
|
||||
|
||||
if (PK11_GenerateRandom((unsigned char *)buffer, length) != SECSuccess)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
232
lib/crypto_backend/crypto_openssl.c
Normal file
232
lib/crypto_backend/crypto_openssl.c
Normal file
@@ -0,0 +1,232 @@
|
||||
/*
|
||||
* OPENSSL crypto backend implementation
|
||||
*
|
||||
* Copyright (C) 2010-2012, 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
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/hmac.h>
|
||||
#include <openssl/rand.h>
|
||||
#include "crypto_backend.h"
|
||||
|
||||
static int crypto_backend_initialised = 0;
|
||||
|
||||
struct crypt_hash {
|
||||
EVP_MD_CTX md;
|
||||
const EVP_MD *hash_id;
|
||||
int hash_len;
|
||||
};
|
||||
|
||||
struct crypt_hmac {
|
||||
HMAC_CTX md;
|
||||
const EVP_MD *hash_id;
|
||||
int hash_len;
|
||||
};
|
||||
|
||||
int crypt_backend_init(struct crypt_device *ctx)
|
||||
{
|
||||
if (crypto_backend_initialised)
|
||||
return 0;
|
||||
|
||||
OpenSSL_add_all_digests();
|
||||
|
||||
crypto_backend_initialised = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t crypt_backend_flags(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *crypt_backend_version(void)
|
||||
{
|
||||
return SSLeay_version(SSLEAY_VERSION);
|
||||
}
|
||||
|
||||
/* HASH */
|
||||
int crypt_hash_size(const char *name)
|
||||
{
|
||||
const EVP_MD *hash_id = EVP_get_digestbyname(name);
|
||||
|
||||
if (!hash_id)
|
||||
return -EINVAL;
|
||||
|
||||
return EVP_MD_size(hash_id);
|
||||
}
|
||||
|
||||
int crypt_hash_init(struct crypt_hash **ctx, const char *name)
|
||||
{
|
||||
struct crypt_hash *h;
|
||||
|
||||
h = malloc(sizeof(*h));
|
||||
if (!h)
|
||||
return -ENOMEM;
|
||||
|
||||
h->hash_id = EVP_get_digestbyname(name);
|
||||
if (!h->hash_id) {
|
||||
free(h);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (EVP_DigestInit(&h->md, h->hash_id) != 1) {
|
||||
free(h);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
h->hash_len = EVP_MD_size(h->hash_id);
|
||||
*ctx = h;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int crypt_hash_restart(struct crypt_hash *ctx)
|
||||
{
|
||||
if (EVP_DigestInit(&ctx->md, ctx->hash_id) != 1)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypt_hash_write(struct crypt_hash *ctx, const char *buffer, size_t length)
|
||||
{
|
||||
if (EVP_DigestUpdate(&ctx->md, buffer, length) != 1)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypt_hash_final(struct crypt_hash *ctx, char *buffer, size_t length)
|
||||
{
|
||||
unsigned char tmp[EVP_MAX_MD_SIZE];
|
||||
unsigned int tmp_len = 0;
|
||||
|
||||
if (length > (size_t)ctx->hash_len)
|
||||
return -EINVAL;
|
||||
|
||||
if (EVP_DigestFinal_ex(&ctx->md, tmp, &tmp_len) != 1)
|
||||
return -EINVAL;
|
||||
|
||||
memcpy(buffer, tmp, length);
|
||||
memset(tmp, 0, sizeof(tmp));
|
||||
|
||||
if (tmp_len < length)
|
||||
return -EINVAL;
|
||||
|
||||
if (crypt_hash_restart(ctx))
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypt_hash_destroy(struct crypt_hash *ctx)
|
||||
{
|
||||
EVP_MD_CTX_cleanup(&ctx->md);
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
free(ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 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 *buffer, size_t length)
|
||||
{
|
||||
struct crypt_hmac *h;
|
||||
|
||||
h = malloc(sizeof(*h));
|
||||
if (!h)
|
||||
return -ENOMEM;
|
||||
|
||||
h->hash_id = EVP_get_digestbyname(name);
|
||||
if (!h->hash_id) {
|
||||
free(h);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
HMAC_CTX_init(&h->md);
|
||||
HMAC_Init_ex(&h->md, buffer, length, h->hash_id, NULL);
|
||||
|
||||
h->hash_len = EVP_MD_size(h->hash_id);
|
||||
*ctx = h;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void crypt_hmac_restart(struct crypt_hmac *ctx)
|
||||
{
|
||||
HMAC_Init_ex(&ctx->md, NULL, 0, ctx->hash_id, NULL);
|
||||
}
|
||||
|
||||
int crypt_hmac_write(struct crypt_hmac *ctx, const char *buffer, size_t length)
|
||||
{
|
||||
HMAC_Update(&ctx->md, (const unsigned char *)buffer, length);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypt_hmac_final(struct crypt_hmac *ctx, char *buffer, size_t length)
|
||||
{
|
||||
unsigned char tmp[EVP_MAX_MD_SIZE];
|
||||
unsigned int tmp_len = 0;
|
||||
|
||||
if (length > (size_t)ctx->hash_len)
|
||||
return -EINVAL;
|
||||
|
||||
HMAC_Final(&ctx->md, tmp, &tmp_len);
|
||||
|
||||
memcpy(buffer, tmp, length);
|
||||
memset(tmp, 0, sizeof(tmp));
|
||||
|
||||
if (tmp_len < length)
|
||||
return -EINVAL;
|
||||
|
||||
crypt_hmac_restart(ctx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypt_hmac_destroy(struct crypt_hmac *ctx)
|
||||
{
|
||||
HMAC_CTX_cleanup(&ctx->md);
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
free(ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* RNG */
|
||||
int crypt_backend_rng(char *buffer, size_t length, int quality, int fips)
|
||||
{
|
||||
if (fips)
|
||||
return -EINVAL;
|
||||
|
||||
if (RAND_bytes((unsigned char *)buffer, length) != 1)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
124
lib/gcrypt.c
124
lib/gcrypt.c
@@ -1,124 +0,0 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <gcrypt.h>
|
||||
|
||||
#include "libcryptsetup.h"
|
||||
#include "internal.h"
|
||||
|
||||
#define MAX_DIGESTS 64
|
||||
#define GCRYPT_REQ_VERSION "1.1.42"
|
||||
|
||||
static int gcrypt_hash(void *data, int size, char *key,
|
||||
int sizep, const char *passphrase)
|
||||
{
|
||||
gcry_md_hd_t md;
|
||||
int algo = *((int *)data);
|
||||
int len = gcry_md_get_algo_dlen(algo);
|
||||
int round, i;
|
||||
|
||||
if (gcry_md_open(&md, algo, 0))
|
||||
return -1;
|
||||
|
||||
for(round = 0; size; round++) {
|
||||
/* hack from hashalot to avoid null bytes in key */
|
||||
for(i = 0; i < round; i++)
|
||||
gcry_md_write(md, "A", 1);
|
||||
|
||||
gcry_md_write(md, passphrase, sizep);
|
||||
|
||||
if (len > size)
|
||||
len = size;
|
||||
memcpy(key, gcry_md_read(md, algo), len);
|
||||
|
||||
key += len;
|
||||
size -= len;
|
||||
if (size)
|
||||
gcry_md_reset(md);
|
||||
}
|
||||
|
||||
gcry_md_close(md);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct hash_type *gcrypt_get_hashes(void)
|
||||
{
|
||||
struct hash_type *hashes;
|
||||
int size = MAX_DIGESTS;
|
||||
int *list;
|
||||
int i;
|
||||
gcry_error_t r;
|
||||
|
||||
if (!gcry_check_version(GCRYPT_REQ_VERSION))
|
||||
return NULL;
|
||||
|
||||
list = (int *)malloc(sizeof(*list) * size);
|
||||
if (!list)
|
||||
return NULL;
|
||||
|
||||
r = gcry_md_list(list, &size);
|
||||
if (r || !size) {
|
||||
free(list);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
hashes = malloc(sizeof(*hashes) * (size + 1));
|
||||
if (!hashes) {
|
||||
free(list);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for(i = 0; i < size; i++) {
|
||||
hashes[i].name = NULL;
|
||||
hashes[i].private = NULL;
|
||||
}
|
||||
|
||||
for(i = 0; i < size; i++) {
|
||||
char *p;
|
||||
|
||||
hashes[i].name = strdup(gcry_md_algo_name(list[i]));
|
||||
if(!hashes[i].name)
|
||||
goto err;
|
||||
for(p = (char *)hashes[i].name; *p; p++)
|
||||
*p = tolower(*p);
|
||||
hashes[i].private = malloc(sizeof(int));
|
||||
if(!hashes[i].private)
|
||||
goto err;
|
||||
*((int *)hashes[i].private) = list[i];
|
||||
hashes[i].fn = gcrypt_hash;
|
||||
}
|
||||
hashes[i].name = NULL;
|
||||
hashes[i].private = NULL;
|
||||
hashes[i].fn = NULL;
|
||||
|
||||
free(list);
|
||||
|
||||
return hashes;
|
||||
|
||||
err:
|
||||
free(list);
|
||||
for(i = 0; i < size; i++) {
|
||||
free(hashes[i].name);
|
||||
free(hashes[i].private);
|
||||
}
|
||||
free(hashes);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void gcrypt_free_hashes(struct hash_type *hashes)
|
||||
{
|
||||
struct hash_type *hash;
|
||||
|
||||
for(hash = hashes; hash->name; hash++) {
|
||||
free(hash->name);
|
||||
free(hash->private);
|
||||
}
|
||||
|
||||
free(hashes);
|
||||
}
|
||||
|
||||
struct hash_backend hash_gcrypt_backend = {
|
||||
.name = "libgcrypt",
|
||||
.get_hashes = gcrypt_get_hashes,
|
||||
.free_hashes = gcrypt_free_hashes
|
||||
};
|
||||
162
lib/internal.h
162
lib/internal.h
@@ -1,3 +1,24 @@
|
||||
/*
|
||||
* libcryptsetup - cryptsetup library internal
|
||||
*
|
||||
* Copyright (C) 2004, Christophe Saout <christophe@saout.de>
|
||||
* Copyright (C) 2004-2007, Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2012, 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
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef INTERNAL_H
|
||||
#define INTERNAL_H
|
||||
|
||||
@@ -8,69 +29,112 @@
|
||||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
#include <unistd.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "nls.h"
|
||||
#include "bitops.h"
|
||||
#include "utils_crypt.h"
|
||||
#include "utils_loop.h"
|
||||
#include "utils_dm.h"
|
||||
#include "utils_fips.h"
|
||||
#include "crypto_backend.h"
|
||||
|
||||
#include "libcryptsetup.h"
|
||||
|
||||
/* to silent gcc -Wcast-qual for const cast */
|
||||
#define CONST_CAST(x) (x)(uintptr_t)
|
||||
|
||||
#define SECTOR_SHIFT 9
|
||||
#define SECTOR_SIZE (1 << SECTOR_SHIFT)
|
||||
#define DEFAULT_DISK_ALIGNMENT 1048576 /* 1MiB */
|
||||
#define DEFAULT_MEM_ALIGNMENT 4096
|
||||
#define MAX_ERROR_LENGTH 512
|
||||
|
||||
/* private struct crypt_options flags */
|
||||
#define at_least(a, b) ({ __typeof__(a) __at_least = (a); (__at_least >= (b))?__at_least:(b); })
|
||||
|
||||
#define CRYPT_FLAG_FREE_DEVICE (1 << 24)
|
||||
#define CRYPT_FLAG_FREE_CIPHER (1 << 25)
|
||||
struct crypt_device;
|
||||
|
||||
#define CRYPT_FLAG_PRIVATE_MASK ((unsigned int)-1 << 24)
|
||||
|
||||
struct hash_type {
|
||||
char *name;
|
||||
void *private;
|
||||
int (*fn)(void *data, int size, char *key,
|
||||
int sizep, const char *passphrase);
|
||||
struct volume_key {
|
||||
size_t keylength;
|
||||
char key[];
|
||||
};
|
||||
|
||||
struct hash_backend {
|
||||
const char *name;
|
||||
struct hash_type * (*get_hashes)(void);
|
||||
void (*free_hashes)(struct hash_type *hashes);
|
||||
};
|
||||
struct volume_key *crypt_alloc_volume_key(unsigned keylength, const char *key);
|
||||
struct volume_key *crypt_generate_volume_key(struct crypt_device *cd, unsigned keylength);
|
||||
void crypt_free_volume_key(struct volume_key *vk);
|
||||
|
||||
struct setup_backend {
|
||||
const char *name;
|
||||
int (*init)(void);
|
||||
void (*exit)(void);
|
||||
int (*create)(int reload, struct crypt_options *options,
|
||||
const char *key, const char *uuid);
|
||||
int (*status)(int details, struct crypt_options *options,
|
||||
char **key);
|
||||
int (*remove)(int force, struct crypt_options *options);
|
||||
int crypt_confirm(struct crypt_device *cd, const char *msg);
|
||||
|
||||
const char * (*dir)(void);
|
||||
};
|
||||
|
||||
void set_error_va(const char *fmt, va_list va);
|
||||
void set_error(const char *fmt, ...);
|
||||
const char *get_error(void);
|
||||
void *safe_alloc(size_t size);
|
||||
void safe_free(void *data);
|
||||
void *safe_realloc(void *data, size_t size);
|
||||
char *safe_strdup(const char *s);
|
||||
|
||||
struct hash_backend *get_hash_backend(const char *name);
|
||||
void put_hash_backend(struct hash_backend *backend);
|
||||
int hash(const char *backend_name, const char *hash_name,
|
||||
char *result, size_t size,
|
||||
const char *passphrase, size_t sizep);
|
||||
|
||||
struct setup_backend *get_setup_backend(const char *name);
|
||||
void put_setup_backend(struct setup_backend *backend);
|
||||
|
||||
void hexprint(char *d, int n);
|
||||
char *crypt_lookup_dev(const char *dev_id);
|
||||
int crypt_sysfs_check_crypt_segment(const char *device, uint64_t offset, uint64_t size);
|
||||
int crypt_sysfs_get_rotational(int major, int minor, int *rotational);
|
||||
|
||||
int sector_size_for_device(const char *device);
|
||||
ssize_t write_blockwise(int fd, const void *buf, size_t count);
|
||||
int device_read_ahead(const char *dev, uint32_t *read_ahead);
|
||||
ssize_t write_blockwise(int fd, void *buf, size_t count);
|
||||
ssize_t read_blockwise(int fd, void *_buf, size_t count);
|
||||
ssize_t write_lseek_blockwise(int fd, const char *buf, size_t count, off_t offset);
|
||||
ssize_t write_lseek_blockwise(int fd, char *buf, size_t count, off_t offset);
|
||||
int device_ready(struct crypt_device *cd, const char *device, int mode);
|
||||
int device_size(const char *device, uint64_t *size);
|
||||
|
||||
unsigned crypt_getpagesize(void);
|
||||
|
||||
int get_key(char *prompt, char **key, unsigned int *passLen, int key_size,
|
||||
const char *key_file, int passphrase_fd, int timeout, int how2verify);
|
||||
enum devcheck { DEV_OK = 0, DEV_EXCL = 1, DEV_SHARED = 2 };
|
||||
int device_check_and_adjust(struct crypt_device *cd,
|
||||
const char *device,
|
||||
enum devcheck device_check,
|
||||
uint64_t *size,
|
||||
uint64_t *offset,
|
||||
uint32_t *flags);
|
||||
|
||||
void logger(struct crypt_device *cd, int class, const char *file, int line, const char *format, ...);
|
||||
#define log_dbg(x...) logger(NULL, CRYPT_LOG_DEBUG, __FILE__, __LINE__, x)
|
||||
#define log_std(c, x...) logger(c, CRYPT_LOG_NORMAL, __FILE__, __LINE__, x)
|
||||
#define log_verbose(c, x...) logger(c, CRYPT_LOG_VERBOSE, __FILE__, __LINE__, x)
|
||||
#define log_err(c, x...) logger(c, CRYPT_LOG_ERROR, __FILE__, __LINE__, x)
|
||||
|
||||
int crypt_get_debug_level(void);
|
||||
|
||||
int crypt_memlock_inc(struct crypt_device *ctx);
|
||||
int crypt_memlock_dec(struct crypt_device *ctx);
|
||||
|
||||
void get_topology_alignment(const char *device,
|
||||
unsigned long *required_alignment, /* bytes */
|
||||
unsigned long *alignment_offset, /* bytes */
|
||||
unsigned long default_alignment);
|
||||
|
||||
int crypt_random_init(struct crypt_device *ctx);
|
||||
int crypt_random_get(struct crypt_device *ctx, char *buf, size_t len, int quality);
|
||||
void crypt_random_exit(void);
|
||||
int crypt_random_default_key_rng(void);
|
||||
|
||||
int crypt_plain_hash(struct crypt_device *ctx,
|
||||
const char *hash_name,
|
||||
char *key, size_t key_size,
|
||||
const char *passphrase, size_t passphrase_size);
|
||||
int PLAIN_activate(struct crypt_device *cd,
|
||||
const char *name,
|
||||
struct volume_key *vk,
|
||||
uint64_t size,
|
||||
uint32_t flags);
|
||||
|
||||
/**
|
||||
* Different methods used to erase sensitive data concerning
|
||||
* either encrypted payload area or master key inside keyslot
|
||||
* area
|
||||
*/
|
||||
typedef enum {
|
||||
CRYPT_WIPE_ZERO, /**< overwrite area using zero blocks */
|
||||
CRYPT_WIPE_DISK, /**< erase disk (using Gutmann method if it is rotational disk)*/
|
||||
CRYPT_WIPE_SSD, /**< erase solid state disk (random write) */
|
||||
CRYPT_WIPE_RANDOM /**< overwrite area using some up to now unspecified
|
||||
* random algorithm */
|
||||
} crypt_wipe_type;
|
||||
|
||||
int crypt_wipe(const char *device,
|
||||
uint64_t offset,
|
||||
uint64_t sectors,
|
||||
crypt_wipe_type type,
|
||||
int flags);
|
||||
|
||||
#endif /* INTERNAL_H */
|
||||
|
||||
1088
lib/libcryptsetup.h
1088
lib/libcryptsetup.h
File diff suppressed because it is too large
Load Diff
10
lib/libcryptsetup.pc.in
Normal file
10
lib/libcryptsetup.pc.in
Normal file
@@ -0,0 +1,10 @@
|
||||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
libdir=@libdir@
|
||||
includedir=@includedir@
|
||||
|
||||
Name: cryptsetup
|
||||
Description: cryptsetup library
|
||||
Version: @LIBCRYPTSETUP_VERSION@
|
||||
Cflags: -I${includedir}
|
||||
Libs: -L${libdir} -lcryptsetup
|
||||
69
lib/libcryptsetup.sym
Normal file
69
lib/libcryptsetup.sym
Normal file
@@ -0,0 +1,69 @@
|
||||
CRYPTSETUP_1.0 {
|
||||
global:
|
||||
crypt_init;
|
||||
crypt_init_by_name;
|
||||
crypt_init_by_name_and_header;
|
||||
crypt_set_log_callback;
|
||||
crypt_set_confirm_callback;
|
||||
crypt_set_password_callback;
|
||||
crypt_set_timeout;
|
||||
crypt_set_password_retry;
|
||||
crypt_set_iterarion_time;
|
||||
crypt_set_iteration_time;
|
||||
crypt_set_password_verify;
|
||||
crypt_set_uuid;
|
||||
crypt_set_data_device;
|
||||
|
||||
crypt_memory_lock;
|
||||
crypt_format;
|
||||
crypt_load;
|
||||
crypt_repair;
|
||||
crypt_resize;
|
||||
crypt_suspend;
|
||||
crypt_resume_by_passphrase;
|
||||
crypt_resume_by_keyfile;
|
||||
crypt_resume_by_keyfile_offset;
|
||||
crypt_free;
|
||||
|
||||
crypt_keyslot_add_by_passphrase;
|
||||
crypt_keyslot_add_by_keyfile;
|
||||
crypt_keyslot_add_by_keyfile_offset;
|
||||
crypt_keyslot_add_by_volume_key;
|
||||
crypt_keyslot_destroy;
|
||||
crypt_activate_by_passphrase;
|
||||
crypt_activate_by_keyfile;
|
||||
crypt_activate_by_keyfile_offset;
|
||||
crypt_activate_by_volume_key;
|
||||
crypt_deactivate;
|
||||
crypt_volume_key_get;
|
||||
crypt_volume_key_verify;
|
||||
crypt_status;
|
||||
crypt_dump;
|
||||
crypt_get_cipher;
|
||||
crypt_get_cipher_mode;
|
||||
crypt_get_uuid;
|
||||
crypt_get_data_offset;
|
||||
crypt_get_iv_offset;
|
||||
crypt_get_volume_key_size;
|
||||
crypt_get_device_name;
|
||||
crypt_get_verity_info;
|
||||
|
||||
crypt_get_type;
|
||||
crypt_get_active_device;
|
||||
|
||||
crypt_set_rng_type;
|
||||
crypt_get_rng_type;
|
||||
|
||||
crypt_keyslot_max;
|
||||
crypt_keyslot_status;
|
||||
crypt_last_error;
|
||||
crypt_get_error;
|
||||
crypt_get_dir;
|
||||
crypt_set_debug_level;
|
||||
crypt_log;
|
||||
|
||||
crypt_header_backup;
|
||||
crypt_header_restore;
|
||||
local:
|
||||
*;
|
||||
};
|
||||
1190
lib/libdevmapper.c
1190
lib/libdevmapper.c
File diff suppressed because it is too large
Load Diff
16
lib/loopaes/Makefile.am
Normal file
16
lib/loopaes/Makefile.am
Normal file
@@ -0,0 +1,16 @@
|
||||
moduledir = $(libdir)/cryptsetup
|
||||
|
||||
noinst_LTLIBRARIES = libloopaes.la
|
||||
|
||||
libloopaes_la_CFLAGS = -Wall @CRYPTO_CFLAGS@
|
||||
|
||||
libloopaes_la_SOURCES = \
|
||||
loopaes.c \
|
||||
loopaes.h
|
||||
|
||||
INCLUDES = -D_GNU_SOURCE \
|
||||
-D_LARGEFILE64_SOURCE \
|
||||
-D_FILE_OFFSET_BITS=64 \
|
||||
-I$(top_srcdir)/lib \
|
||||
-I$(top_srcdir)/lib/crypto_backend
|
||||
|
||||
237
lib/loopaes/loopaes.c
Normal file
237
lib/loopaes/loopaes.c
Normal file
@@ -0,0 +1,237 @@
|
||||
/*
|
||||
* loop-AES compatible volume handling
|
||||
*
|
||||
* Copyright (C) 2011-2012, 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
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "libcryptsetup.h"
|
||||
#include "loopaes.h"
|
||||
#include "internal.h"
|
||||
|
||||
static const char *get_hash(unsigned int key_size)
|
||||
{
|
||||
const char *hash;
|
||||
|
||||
switch (key_size) {
|
||||
case 16: hash = "sha256"; break;
|
||||
case 24: hash = "sha384"; break;
|
||||
case 32: hash = "sha512"; break;
|
||||
default: hash = NULL;
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
static unsigned char get_tweak(unsigned int keys_count)
|
||||
{
|
||||
switch (keys_count) {
|
||||
case 64: return 0x55;
|
||||
case 65: return 0xF4;
|
||||
default: break;
|
||||
}
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
static int hash_key(const char *src, size_t src_len,
|
||||
char *dst, size_t dst_len,
|
||||
const char *hash_name)
|
||||
{
|
||||
struct crypt_hash *hd = NULL;
|
||||
int r;
|
||||
|
||||
if (crypt_hash_init(&hd, hash_name))
|
||||
return -EINVAL;
|
||||
|
||||
r = crypt_hash_write(hd, src, src_len);
|
||||
if (!r)
|
||||
r = crypt_hash_final(hd, dst, dst_len);
|
||||
|
||||
crypt_hash_destroy(hd);
|
||||
return r;
|
||||
}
|
||||
|
||||
static int hash_keys(struct crypt_device *cd,
|
||||
struct volume_key **vk,
|
||||
const char *hash_override,
|
||||
const char **input_keys,
|
||||
unsigned int keys_count,
|
||||
unsigned int key_len_output)
|
||||
{
|
||||
const char *hash_name;
|
||||
char tweak, *key_ptr;
|
||||
unsigned i, key_len_input;
|
||||
int r;
|
||||
|
||||
hash_name = hash_override ?: get_hash(key_len_output);
|
||||
tweak = get_tweak(keys_count);
|
||||
key_len_input = strlen(input_keys[0]);
|
||||
|
||||
if (!keys_count || !key_len_output || !hash_name || !key_len_input) {
|
||||
log_err(cd, _("Key processing error (using hash %s).\n"),
|
||||
hash_name ?: "[none]");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
*vk = crypt_alloc_volume_key(key_len_output * keys_count, NULL);
|
||||
if (!*vk)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < keys_count; i++) {
|
||||
key_ptr = &(*vk)->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;
|
||||
|
||||
key_ptr[0] ^= tweak;
|
||||
}
|
||||
|
||||
if (r < 0 && *vk) {
|
||||
crypt_free_volume_key(*vk);
|
||||
*vk = NULL;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
static int keyfile_is_gpg(char *buffer, size_t buffer_len)
|
||||
{
|
||||
int r = 0;
|
||||
int index = buffer_len < 100 ? buffer_len - 1 : 100;
|
||||
char eos = buffer[index];
|
||||
|
||||
buffer[index] = '\0';
|
||||
if (strstr(buffer, "BEGIN PGP MESSAGE"))
|
||||
r = 1;
|
||||
buffer[index] = eos;
|
||||
return r;
|
||||
}
|
||||
|
||||
int LOOPAES_parse_keyfile(struct crypt_device *cd,
|
||||
struct volume_key **vk,
|
||||
const char *hash,
|
||||
unsigned int *keys_count,
|
||||
char *buffer,
|
||||
size_t buffer_len)
|
||||
{
|
||||
const char *keys[LOOPAES_KEYS_MAX];
|
||||
unsigned i, key_index, key_len, offset;
|
||||
|
||||
log_dbg("Parsing loop-AES keyfile of size %d.", buffer_len);
|
||||
|
||||
if (!buffer_len)
|
||||
return -EINVAL;
|
||||
|
||||
if (keyfile_is_gpg(buffer, buffer_len)) {
|
||||
log_err(cd, _("Detected not yet supported GPG encrypted keyfile.\n"));
|
||||
log_std(cd, _("Please use gpg --decrypt <KEYFILE> | cryptsetup --keyfile=- ...\n"));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Remove EOL in buffer */
|
||||
for (i = 0; i < buffer_len; i++)
|
||||
if (buffer[i] == '\n' || buffer[i] == '\r')
|
||||
buffer[i] = '\0';
|
||||
|
||||
offset = 0;
|
||||
key_index = 0;
|
||||
while (offset < buffer_len && key_index < LOOPAES_KEYS_MAX) {
|
||||
keys[key_index++] = &buffer[offset];
|
||||
while (offset < buffer_len && buffer[offset])
|
||||
offset++;
|
||||
while (offset < buffer_len && !buffer[offset])
|
||||
offset++;
|
||||
}
|
||||
|
||||
/* All keys must be the same length */
|
||||
key_len = key_index ? strlen(keys[0]) : 0;
|
||||
for (i = 0; i < key_index; i++)
|
||||
if (key_len != strlen(keys[i])) {
|
||||
log_dbg("Unexpected length %d of key #%d (should be %d).",
|
||||
strlen(keys[i]), i, key_len);
|
||||
key_len = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
log_dbg("Keyfile: %d keys of length %d.", key_index, key_len);
|
||||
if (offset != buffer_len || key_len == 0 ||
|
||||
(key_index != 1 && key_index !=64 && key_index != 65)) {
|
||||
log_err(cd, _("Incompatible loop-AES keyfile detected.\n"));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
*keys_count = key_index;
|
||||
return hash_keys(cd, vk, hash, keys, key_index, crypt_get_volume_key_size(cd));
|
||||
}
|
||||
|
||||
int LOOPAES_activate(struct crypt_device *cd,
|
||||
const char *name,
|
||||
const char *base_cipher,
|
||||
unsigned int keys_count,
|
||||
struct volume_key *vk,
|
||||
uint32_t flags)
|
||||
{
|
||||
char *cipher = NULL;
|
||||
uint32_t req_flags;
|
||||
int r;
|
||||
struct crypt_dm_active_device dmd = {
|
||||
.target = DM_CRYPT,
|
||||
.uuid = crypt_get_uuid(cd),
|
||||
.size = 0,
|
||||
.flags = flags,
|
||||
.data_device = crypt_get_device_name(cd),
|
||||
.u.crypt = {
|
||||
.cipher = NULL,
|
||||
.vk = vk,
|
||||
.offset = crypt_get_data_offset(cd),
|
||||
.iv_offset = crypt_get_iv_offset(cd),
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
r = device_check_and_adjust(cd, dmd.data_device, DEV_EXCL,
|
||||
&dmd.size, &dmd.u.crypt.offset, &flags);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
if (keys_count == 1) {
|
||||
req_flags = DM_PLAIN64_SUPPORTED;
|
||||
r = asprintf(&cipher, "%s-%s", base_cipher, "cbc-plain64");
|
||||
} else {
|
||||
req_flags = DM_LMK_SUPPORTED;
|
||||
r = asprintf(&cipher, "%s:%d-%s", base_cipher, 64, "cbc-lmk");
|
||||
}
|
||||
if (r < 0)
|
||||
return -ENOMEM;
|
||||
|
||||
dmd.u.crypt.cipher = cipher;
|
||||
log_dbg("Trying to activate loop-AES device %s using cipher %s.",
|
||||
name, dmd.u.crypt.cipher);
|
||||
|
||||
r = dm_create_device(name, CRYPT_LOOPAES, &dmd, 0);
|
||||
|
||||
if (!r && !(dm_flags() & req_flags)) {
|
||||
log_err(cd, _("Kernel doesn't support loop-AES compatible mapping.\n"));
|
||||
r = -ENOTSUP;
|
||||
}
|
||||
|
||||
free(cipher);
|
||||
return r;
|
||||
}
|
||||
44
lib/loopaes/loopaes.h
Normal file
44
lib/loopaes/loopaes.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* loop-AES compatible volume handling
|
||||
*
|
||||
* Copyright (C) 2011-2012, 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
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _LOOPAES_H
|
||||
#define _LOOPAES_H
|
||||
|
||||
#include <unistd.h>
|
||||
#include "config.h"
|
||||
|
||||
struct crypt_device;
|
||||
struct volume_key;
|
||||
|
||||
#define LOOPAES_KEYS_MAX 65
|
||||
|
||||
int LOOPAES_parse_keyfile(struct crypt_device *cd,
|
||||
struct volume_key **vk,
|
||||
const char *hash,
|
||||
unsigned int *keys_count,
|
||||
char *buffer,
|
||||
size_t buffer_len);
|
||||
|
||||
int LOOPAES_activate(struct crypt_device *cd,
|
||||
const char *name,
|
||||
const char *base_cipher,
|
||||
unsigned int keys_count,
|
||||
struct volume_key *vk,
|
||||
uint32_t flags);
|
||||
#endif
|
||||
21
lib/luks1/Makefile.am
Normal file
21
lib/luks1/Makefile.am
Normal file
@@ -0,0 +1,21 @@
|
||||
moduledir = $(libdir)/cryptsetup
|
||||
|
||||
noinst_LTLIBRARIES = libluks1.la
|
||||
|
||||
libluks1_la_CFLAGS = -Wall @CRYPTO_CFLAGS@
|
||||
|
||||
libluks1_la_SOURCES = \
|
||||
af.c \
|
||||
pbkdf.c \
|
||||
keymanage.c \
|
||||
keyencryption.c \
|
||||
pbkdf.h \
|
||||
af.h \
|
||||
luks.h
|
||||
|
||||
INCLUDES = -D_GNU_SOURCE \
|
||||
-D_LARGEFILE64_SOURCE \
|
||||
-D_FILE_OFFSET_BITS=64 \
|
||||
-I$(top_srcdir)/lib \
|
||||
-I$(top_srcdir)/lib/crypto_backend
|
||||
|
||||
143
lib/luks1/af.c
Normal file
143
lib/luks1/af.c
Normal file
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
* AFsplitter - Anti forensic information splitter
|
||||
*
|
||||
* Copyright (C) 2004, Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2012, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* AFsplitter diffuses information over a large stripe of data,
|
||||
* therefor 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
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* 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>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <netinet/in.h>
|
||||
#include <errno.h>
|
||||
#include "internal.h"
|
||||
#include "af.h"
|
||||
|
||||
static void XORblock(const char *src1, const char *src2, char *dst, size_t n)
|
||||
{
|
||||
size_t j;
|
||||
|
||||
for(j = 0; j < n; ++j)
|
||||
dst[j] = src1[j] ^ src2[j];
|
||||
}
|
||||
|
||||
static int hash_buf(const char *src, char *dst, uint32_t iv,
|
||||
size_t len, const char *hash_name)
|
||||
{
|
||||
struct crypt_hash *hd = NULL;
|
||||
char *iv_char = (char *)&iv;
|
||||
int r;
|
||||
|
||||
iv = htonl(iv);
|
||||
if (crypt_hash_init(&hd, hash_name))
|
||||
return -EINVAL;
|
||||
|
||||
if ((r = crypt_hash_write(hd, iv_char, sizeof(uint32_t))))
|
||||
goto out;
|
||||
|
||||
if ((r = crypt_hash_write(hd, src, len)))
|
||||
goto out;
|
||||
|
||||
r = crypt_hash_final(hd, dst, len);
|
||||
out:
|
||||
crypt_hash_destroy(hd);
|
||||
return r;
|
||||
}
|
||||
|
||||
/* diffuse: Information spreading over the whole dataset with
|
||||
* the help of hash function.
|
||||
*/
|
||||
|
||||
static int diffuse(char *src, char *dst, size_t size, const char *hash_name)
|
||||
{
|
||||
unsigned int digest_size = crypt_hash_size(hash_name);
|
||||
unsigned int i, blocks, padding;
|
||||
|
||||
blocks = size / digest_size;
|
||||
padding = size % digest_size;
|
||||
|
||||
for (i = 0; i < blocks; i++)
|
||||
if(hash_buf(src + digest_size * i,
|
||||
dst + digest_size * i,
|
||||
i, (size_t)digest_size, hash_name))
|
||||
return 1;
|
||||
|
||||
if(padding)
|
||||
if(hash_buf(src + digest_size * i,
|
||||
dst + digest_size * i,
|
||||
i, (size_t)padding, hash_name))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Information splitting. The amount of data is multiplied by
|
||||
* blocknumbers. The same blocksize and blocknumbers values
|
||||
* must be supplied to AF_merge to recover information.
|
||||
*/
|
||||
|
||||
int AF_split(char *src, char *dst, size_t blocksize,
|
||||
unsigned int blocknumbers, const char *hash)
|
||||
{
|
||||
unsigned int i;
|
||||
char *bufblock;
|
||||
int r = -EINVAL;
|
||||
|
||||
if((bufblock = calloc(blocksize, 1)) == NULL) return -ENOMEM;
|
||||
|
||||
/* process everything except the last block */
|
||||
for(i=0; i<blocknumbers-1; i++) {
|
||||
r = crypt_random_get(NULL, dst+(blocksize*i), blocksize, CRYPT_RND_NORMAL);
|
||||
if(r < 0) goto out;
|
||||
|
||||
XORblock(dst+(blocksize*i),bufblock,bufblock,blocksize);
|
||||
if(diffuse(bufblock, bufblock, blocksize, hash))
|
||||
goto out;
|
||||
}
|
||||
/* the last block is computed */
|
||||
XORblock(src,bufblock,dst+(i*blocksize),blocksize);
|
||||
r = 0;
|
||||
out:
|
||||
free(bufblock);
|
||||
return r;
|
||||
}
|
||||
|
||||
int AF_merge(char *src, char *dst, size_t blocksize,
|
||||
unsigned int blocknumbers, const char *hash)
|
||||
{
|
||||
unsigned int i;
|
||||
char *bufblock;
|
||||
int r = -EINVAL;
|
||||
|
||||
if((bufblock = calloc(blocksize, 1)) == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
memset(bufblock,0,blocksize);
|
||||
for(i=0; i<blocknumbers-1; i++) {
|
||||
XORblock(src+(blocksize*i),bufblock,bufblock,blocksize);
|
||||
if(diffuse(bufblock, bufblock, blocksize, hash))
|
||||
goto out;
|
||||
}
|
||||
XORblock(src + blocksize * i, bufblock, dst, blocksize);
|
||||
r = 0;
|
||||
out:
|
||||
free(bufblock);
|
||||
return r;
|
||||
}
|
||||
42
lib/luks1/af.h
Normal file
42
lib/luks1/af.h
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* AFsplitter - Anti forensic information splitter
|
||||
*
|
||||
* Copyright (C) 2004, Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2012, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* AFsplitter diffuses information over a large stripe of data,
|
||||
* therefor 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
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#ifndef INCLUDED_CRYPTSETUP_LUKS_AF_H
|
||||
#define INCLUDED_CRYPTSETUP_LUKS_AF_H
|
||||
|
||||
/*
|
||||
* AF_split operates on src and produces information split data in
|
||||
* dst. src is assumed to be of the length blocksize. The data stripe
|
||||
* dst points to must be capable of storing blocksize*blocknumbers.
|
||||
* blocknumbers is the data multiplication factor.
|
||||
*
|
||||
* AF_merge does just the opposite: reproduces the information stored in
|
||||
* src of the length blocksize*blocknumbers into dst of the length
|
||||
* blocksize.
|
||||
*
|
||||
* On error, both functions return -1, 0 otherwise.
|
||||
*/
|
||||
|
||||
int AF_split(char *src, char *dst, size_t blocksize, unsigned int blocknumbers, const char *hash);
|
||||
int AF_merge(char *src, char *dst, size_t blocksize, unsigned int blocknumbers, const char *hash);
|
||||
|
||||
#endif
|
||||
206
lib/luks1/keyencryption.c
Normal file
206
lib/luks1/keyencryption.c
Normal file
@@ -0,0 +1,206 @@
|
||||
/*
|
||||
* LUKS - Linux Unified Key Setup
|
||||
*
|
||||
* Copyright (C) 2004-2006, Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2012, 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
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <inttypes.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/utsname.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include "luks.h"
|
||||
#include "internal.h"
|
||||
|
||||
#define div_round_up(a,b) ({ \
|
||||
typeof(a) __a = (a); \
|
||||
typeof(b) __b = (b); \
|
||||
(__a - 1) / __b + 1; \
|
||||
})
|
||||
|
||||
static inline int round_up_modulo(int x, int m) {
|
||||
return div_round_up(x, m) * m;
|
||||
}
|
||||
|
||||
static const char *cleaner_name=NULL;
|
||||
static uint64_t cleaner_size = 0;
|
||||
static int devfd=-1;
|
||||
|
||||
static int setup_mapping(const char *cipher, const char *name,
|
||||
const char *device,
|
||||
struct volume_key *vk,
|
||||
unsigned int sector, size_t srcLength,
|
||||
int mode, struct crypt_device *ctx)
|
||||
{
|
||||
int device_sector_size = sector_size_for_device(device);
|
||||
struct crypt_dm_active_device dmd = {
|
||||
.target = DM_CRYPT,
|
||||
.uuid = NULL,
|
||||
.size = 0,
|
||||
.flags = 0,
|
||||
.data_device = device,
|
||||
.u.crypt = {
|
||||
.cipher = cipher,
|
||||
.vk = vk,
|
||||
.offset = sector,
|
||||
.iv_offset = 0,
|
||||
}
|
||||
};
|
||||
|
||||
dmd.flags = CRYPT_ACTIVATE_PRIVATE;
|
||||
if (mode == O_RDONLY)
|
||||
dmd.flags |= CRYPT_ACTIVATE_READONLY;
|
||||
/*
|
||||
* we need to round this to nearest multiple of the underlying
|
||||
* device's sector size, otherwise the mapping will be refused.
|
||||
*/
|
||||
if(device_sector_size < 0) {
|
||||
log_err(ctx, _("Unable to obtain sector size for %s"), device);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
dmd.size = round_up_modulo(srcLength,device_sector_size)/SECTOR_SIZE;
|
||||
cleaner_size = dmd.size;
|
||||
|
||||
return dm_create_device(name, "TEMP", &dmd, 0);
|
||||
}
|
||||
|
||||
static void sigint_handler(int sig __attribute__((unused)))
|
||||
{
|
||||
if(devfd >= 0)
|
||||
close(devfd);
|
||||
devfd = -1;
|
||||
if(cleaner_name)
|
||||
dm_remove_device(cleaner_name, 1, cleaner_size);
|
||||
|
||||
signal(SIGINT, SIG_DFL);
|
||||
kill(getpid(), SIGINT);
|
||||
}
|
||||
|
||||
static const char *_error_hint(char *cipherMode, size_t keyLength)
|
||||
{
|
||||
const char *hint= "";
|
||||
|
||||
if (!strncmp(cipherMode, "xts", 3) && (keyLength != 256 && keyLength != 512))
|
||||
hint = _("Key size in XTS mode must be 256 or 512 bits.\n");
|
||||
|
||||
return hint;
|
||||
}
|
||||
|
||||
/* This function is not reentrant safe, as it installs a signal
|
||||
handler and global vars for cleaning */
|
||||
static int LUKS_endec_template(char *src, size_t srcLength,
|
||||
struct luks_phdr *hdr,
|
||||
struct volume_key *vk,
|
||||
const char *device,
|
||||
unsigned int sector,
|
||||
ssize_t (*func)(int, void *, size_t),
|
||||
int mode,
|
||||
struct crypt_device *ctx)
|
||||
{
|
||||
char *name = NULL;
|
||||
char *fullpath = NULL;
|
||||
char *dmCipherSpec = NULL;
|
||||
const char *dmDir = dm_get_dir();
|
||||
int r = -1;
|
||||
|
||||
if(dmDir == NULL) {
|
||||
log_err(ctx, _("Failed to obtain device mapper directory."));
|
||||
return -1;
|
||||
}
|
||||
if(asprintf(&name,"temporary-cryptsetup-%d",getpid()) == -1 ||
|
||||
asprintf(&fullpath,"%s/%s",dmDir,name) == -1 ||
|
||||
asprintf(&dmCipherSpec,"%s-%s",hdr->cipherName, hdr->cipherMode) == -1) {
|
||||
r = -ENOMEM;
|
||||
goto out1;
|
||||
}
|
||||
|
||||
signal(SIGINT, sigint_handler);
|
||||
cleaner_name = name;
|
||||
|
||||
r = setup_mapping(dmCipherSpec, name, device,
|
||||
vk, sector, srcLength, mode, ctx);
|
||||
if(r < 0) {
|
||||
log_err(ctx, _("Failed to setup dm-crypt key mapping for device %s.\n"
|
||||
"Check that kernel supports %s cipher (check syslog for more info).\n%s"),
|
||||
device, dmCipherSpec,
|
||||
_error_hint(hdr->cipherMode, vk->keylength * 8));
|
||||
r = -EIO;
|
||||
goto out1;
|
||||
}
|
||||
|
||||
devfd = open(fullpath, mode | O_DIRECT | O_SYNC); /* devfd is a global var */
|
||||
if(devfd == -1) {
|
||||
log_err(ctx, _("Failed to open temporary keystore device.\n"));
|
||||
r = -EIO;
|
||||
goto out2;
|
||||
}
|
||||
|
||||
r = func(devfd,src,srcLength);
|
||||
if(r < 0) {
|
||||
log_err(ctx, _("Failed to access temporary keystore device.\n"));
|
||||
r = -EIO;
|
||||
goto out3;
|
||||
}
|
||||
|
||||
r = 0;
|
||||
out3:
|
||||
close(devfd);
|
||||
devfd = -1;
|
||||
out2:
|
||||
dm_remove_device(cleaner_name, 1, cleaner_size);
|
||||
out1:
|
||||
signal(SIGINT, SIG_DFL);
|
||||
cleaner_name = NULL;
|
||||
cleaner_size = 0;
|
||||
free(dmCipherSpec);
|
||||
free(fullpath);
|
||||
free(name);
|
||||
return r;
|
||||
}
|
||||
|
||||
int LUKS_encrypt_to_storage(char *src, size_t srcLength,
|
||||
struct luks_phdr *hdr,
|
||||
struct volume_key *vk,
|
||||
const char *device,
|
||||
unsigned int sector,
|
||||
struct crypt_device *ctx)
|
||||
{
|
||||
return LUKS_endec_template(src,srcLength,hdr,vk, device,
|
||||
sector, write_blockwise, O_RDWR, ctx);
|
||||
}
|
||||
|
||||
int LUKS_decrypt_from_storage(char *dst, size_t dstLength,
|
||||
struct luks_phdr *hdr,
|
||||
struct volume_key *vk,
|
||||
const char *device,
|
||||
unsigned int sector,
|
||||
struct crypt_device *ctx)
|
||||
{
|
||||
return LUKS_endec_template(dst,dstLength,hdr,vk, device,
|
||||
sector, read_blockwise, O_RDONLY, ctx);
|
||||
}
|
||||
1080
lib/luks1/keymanage.c
Normal file
1080
lib/luks1/keymanage.c
Normal file
File diff suppressed because it is too large
Load Diff
203
lib/luks1/luks.h
Normal file
203
lib/luks1/luks.h
Normal file
@@ -0,0 +1,203 @@
|
||||
/*
|
||||
* LUKS - Linux Unified Key Setup
|
||||
*
|
||||
* Copyright (C) 2004-2006, Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2012, 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
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_CRYPTSETUP_LUKS_LUKS_H
|
||||
#define INCLUDED_CRYPTSETUP_LUKS_LUKS_H
|
||||
|
||||
/*
|
||||
* LUKS partition header
|
||||
*/
|
||||
|
||||
#include "libcryptsetup.h"
|
||||
|
||||
#define LUKS_CIPHERNAME_L 32
|
||||
#define LUKS_CIPHERMODE_L 32
|
||||
#define LUKS_HASHSPEC_L 32
|
||||
#define LUKS_DIGESTSIZE 20 // since SHA1
|
||||
#define LUKS_HMACSIZE 32
|
||||
#define LUKS_SALTSIZE 32
|
||||
#define LUKS_NUMKEYS 8
|
||||
|
||||
// Minimal number of iterations
|
||||
#define LUKS_MKD_ITERATIONS_MIN 1000
|
||||
#define LUKS_SLOT_ITERATIONS_MIN 1000
|
||||
|
||||
#define LUKS_KEY_DISABLED_OLD 0
|
||||
#define LUKS_KEY_ENABLED_OLD 0xCAFE
|
||||
|
||||
#define LUKS_KEY_DISABLED 0x0000DEAD
|
||||
#define LUKS_KEY_ENABLED 0x00AC71F3
|
||||
|
||||
#define LUKS_STRIPES 4000
|
||||
|
||||
// partition header starts with magic
|
||||
#define LUKS_MAGIC {'L','U','K','S', 0xba, 0xbe};
|
||||
#define LUKS_MAGIC_L 6
|
||||
|
||||
#define LUKS_PHDR_SIZE (sizeof(struct luks_phdr)/SECTOR_SIZE+1)
|
||||
|
||||
/* Actually we need only 37, but we don't want struct autoaligning to kick in */
|
||||
#define UUID_STRING_L 40
|
||||
|
||||
/* Offset to keyslot area [in bytes] */
|
||||
#define LUKS_ALIGN_KEYSLOTS 4096
|
||||
|
||||
/* Any integer values are stored in network byte order on disk and must be
|
||||
converted */
|
||||
|
||||
struct volume_key;
|
||||
|
||||
struct luks_phdr {
|
||||
char magic[LUKS_MAGIC_L];
|
||||
uint16_t version;
|
||||
char cipherName[LUKS_CIPHERNAME_L];
|
||||
char cipherMode[LUKS_CIPHERMODE_L];
|
||||
char hashSpec[LUKS_HASHSPEC_L];
|
||||
uint32_t payloadOffset;
|
||||
uint32_t keyBytes;
|
||||
char mkDigest[LUKS_DIGESTSIZE];
|
||||
char mkDigestSalt[LUKS_SALTSIZE];
|
||||
uint32_t mkDigestIterations;
|
||||
char uuid[UUID_STRING_L];
|
||||
|
||||
struct {
|
||||
uint32_t active;
|
||||
|
||||
/* parameters used for password processing */
|
||||
uint32_t passwordIterations;
|
||||
char passwordSalt[LUKS_SALTSIZE];
|
||||
|
||||
/* parameters used for AF store/load */
|
||||
uint32_t keyMaterialOffset;
|
||||
uint32_t stripes;
|
||||
} keyblock[LUKS_NUMKEYS];
|
||||
|
||||
/* Align it to 512 sector size */
|
||||
char _padding[432];
|
||||
};
|
||||
|
||||
int LUKS_verify_volume_key(const struct luks_phdr *hdr,
|
||||
const struct volume_key *vk);
|
||||
|
||||
int LUKS_generate_phdr(
|
||||
struct luks_phdr *header,
|
||||
const struct volume_key *vk,
|
||||
const char *cipherName,
|
||||
const char *cipherMode,
|
||||
const char *hashSpec,
|
||||
const char *uuid,
|
||||
unsigned int stripes,
|
||||
unsigned int alignPayload,
|
||||
unsigned int alignOffset,
|
||||
uint32_t iteration_time_ms,
|
||||
uint64_t *PBKDF2_per_sec,
|
||||
const char *metadata_device,
|
||||
struct crypt_device *ctx);
|
||||
|
||||
int LUKS_read_phdr(
|
||||
const char *device,
|
||||
struct luks_phdr *hdr,
|
||||
int require_luks_device,
|
||||
int repair,
|
||||
struct crypt_device *ctx);
|
||||
|
||||
int LUKS_read_phdr_backup(
|
||||
const char *backup_file,
|
||||
const char *device,
|
||||
struct luks_phdr *hdr,
|
||||
int require_luks_device,
|
||||
struct crypt_device *ctx);
|
||||
|
||||
int LUKS_hdr_uuid_set(
|
||||
const char *device,
|
||||
struct luks_phdr *hdr,
|
||||
const char *uuid,
|
||||
struct crypt_device *ctx);
|
||||
|
||||
int LUKS_hdr_backup(
|
||||
const char *backup_file,
|
||||
const char *device,
|
||||
struct luks_phdr *hdr,
|
||||
struct crypt_device *ctx);
|
||||
|
||||
int LUKS_hdr_restore(
|
||||
const char *backup_file,
|
||||
const char *device,
|
||||
struct luks_phdr *hdr,
|
||||
struct crypt_device *ctx);
|
||||
|
||||
int LUKS_write_phdr(
|
||||
const char *device,
|
||||
struct luks_phdr *hdr,
|
||||
struct crypt_device *ctx);
|
||||
|
||||
int LUKS_set_key(
|
||||
const char *device,
|
||||
unsigned int keyIndex,
|
||||
const char *password,
|
||||
size_t passwordLen,
|
||||
struct luks_phdr *hdr,
|
||||
struct volume_key *vk,
|
||||
uint32_t iteration_time_ms,
|
||||
uint64_t *PBKDF2_per_sec,
|
||||
struct crypt_device *ctx);
|
||||
|
||||
int LUKS_open_key_with_hdr(
|
||||
const char *device,
|
||||
int keyIndex,
|
||||
const char *password,
|
||||
size_t passwordLen,
|
||||
struct luks_phdr *hdr,
|
||||
struct volume_key **vk,
|
||||
struct crypt_device *ctx);
|
||||
|
||||
int LUKS_del_key(
|
||||
const char *device,
|
||||
unsigned int keyIndex,
|
||||
struct luks_phdr *hdr,
|
||||
struct crypt_device *ctx);
|
||||
|
||||
crypt_keyslot_info LUKS_keyslot_info(struct luks_phdr *hdr, int keyslot);
|
||||
int LUKS_keyslot_find_empty(struct luks_phdr *hdr);
|
||||
int LUKS_keyslot_active_count(struct luks_phdr *hdr);
|
||||
int LUKS_keyslot_set(struct luks_phdr *hdr, int keyslot, int enable);
|
||||
|
||||
int LUKS_encrypt_to_storage(
|
||||
char *src, size_t srcLength,
|
||||
struct luks_phdr *hdr,
|
||||
struct volume_key *vk,
|
||||
const char *device,
|
||||
unsigned int sector,
|
||||
struct crypt_device *ctx);
|
||||
|
||||
int LUKS_decrypt_from_storage(
|
||||
char *dst, size_t dstLength,
|
||||
struct luks_phdr *hdr,
|
||||
struct volume_key *vk,
|
||||
const char *device,
|
||||
unsigned int sector,
|
||||
struct crypt_device *ctx);
|
||||
|
||||
int LUKS1_activate(struct crypt_device *cd,
|
||||
const char *name,
|
||||
struct volume_key *vk,
|
||||
uint32_t flags);
|
||||
|
||||
#endif
|
||||
267
lib/luks1/pbkdf.c
Normal file
267
lib/luks1/pbkdf.c
Normal file
@@ -0,0 +1,267 @@
|
||||
/*
|
||||
* Implementation of Password-Based Cryptography as per PKCS#5
|
||||
* Copyright (C) 2002,2003 Simon Josefsson
|
||||
* Copyright (C) 2004 Free Software Foundation
|
||||
*
|
||||
* LUKS code
|
||||
* Copyright (C) 2004, Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2012, 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <alloca.h>
|
||||
#include <string.h>
|
||||
#include <sys/time.h>
|
||||
#include "crypto_backend.h"
|
||||
#include "pbkdf.h"
|
||||
|
||||
static volatile uint64_t __PBKDF2_global_j = 0;
|
||||
static volatile uint64_t __PBKDF2_performance = 0;
|
||||
|
||||
/*
|
||||
* 5.2 PBKDF2
|
||||
*
|
||||
* PBKDF2 applies a pseudorandom function (see Appendix B.1 for an
|
||||
* example) to derive keys. The length of the derived key is essentially
|
||||
* unbounded. (However, the maximum effective search space for the
|
||||
* derived key may be limited by the structure of the underlying
|
||||
* pseudorandom function. See Appendix B.1 for further discussion.)
|
||||
* PBKDF2 is recommended for new applications.
|
||||
*
|
||||
* PBKDF2 (P, S, c, dkLen)
|
||||
*
|
||||
* Options: PRF underlying pseudorandom function (hLen
|
||||
* denotes the length in octets of the
|
||||
* pseudorandom function output)
|
||||
*
|
||||
* Input: P password, an octet string (ASCII or UTF-8)
|
||||
* S salt, an octet string
|
||||
* c iteration count, a positive integer
|
||||
* dkLen intended length in octets of the derived
|
||||
* key, a positive integer, at most
|
||||
* (2^32 - 1) * hLen
|
||||
*
|
||||
* Output: DK derived key, a dkLen-octet string
|
||||
*/
|
||||
|
||||
#define MAX_PRF_BLOCK_LEN 80
|
||||
|
||||
static int pkcs5_pbkdf2(const char *hash,
|
||||
const char *P, size_t Plen,
|
||||
const char *S, size_t Slen,
|
||||
unsigned int c, unsigned int dkLen,
|
||||
char *DK, int perfcheck)
|
||||
{
|
||||
struct crypt_hmac *hmac;
|
||||
char U[MAX_PRF_BLOCK_LEN];
|
||||
char T[MAX_PRF_BLOCK_LEN];
|
||||
int i, k, rc = -EINVAL;
|
||||
unsigned int u, hLen, l, r;
|
||||
size_t tmplen = Slen + 4;
|
||||
char *tmp;
|
||||
|
||||
tmp = alloca(tmplen);
|
||||
if (tmp == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
hLen = crypt_hmac_size(hash);
|
||||
if (hLen == 0 || hLen > MAX_PRF_BLOCK_LEN)
|
||||
return -EINVAL;
|
||||
|
||||
if (c == 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (dkLen == 0)
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
*
|
||||
* Steps:
|
||||
*
|
||||
* 1. If dkLen > (2^32 - 1) * hLen, output "derived key too long" and
|
||||
* stop.
|
||||
*/
|
||||
|
||||
if (dkLen > 4294967295U)
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* 2. Let l be the number of hLen-octet blocks in the derived key,
|
||||
* rounding up, and let r be the number of octets in the last
|
||||
* block:
|
||||
*
|
||||
* l = CEIL (dkLen / hLen) ,
|
||||
* r = dkLen - (l - 1) * hLen .
|
||||
*
|
||||
* Here, CEIL (x) is the "ceiling" function, i.e. the smallest
|
||||
* integer greater than, or equal to, x.
|
||||
*/
|
||||
|
||||
l = dkLen / hLen;
|
||||
if (dkLen % hLen)
|
||||
l++;
|
||||
r = dkLen - (l - 1) * hLen;
|
||||
|
||||
/*
|
||||
* 3. For each block of the derived key apply the function F defined
|
||||
* below to the password P, the salt S, the iteration count c, and
|
||||
* the block index to compute the block:
|
||||
*
|
||||
* T_1 = F (P, S, c, 1) ,
|
||||
* T_2 = F (P, S, c, 2) ,
|
||||
* ...
|
||||
* T_l = F (P, S, c, l) ,
|
||||
*
|
||||
* where the function F is defined as the exclusive-or sum of the
|
||||
* first c iterates of the underlying pseudorandom function PRF
|
||||
* applied to the password P and the concatenation of the salt S
|
||||
* and the block index i:
|
||||
*
|
||||
* F (P, S, c, i) = U_1 \xor U_2 \xor ... \xor U_c
|
||||
*
|
||||
* where
|
||||
*
|
||||
* U_1 = PRF (P, S || INT (i)) ,
|
||||
* U_2 = PRF (P, U_1) ,
|
||||
* ...
|
||||
* U_c = PRF (P, U_{c-1}) .
|
||||
*
|
||||
* Here, INT (i) is a four-octet encoding of the integer i, most
|
||||
* significant octet first.
|
||||
*
|
||||
* 4. Concatenate the blocks and extract the first dkLen octets to
|
||||
* produce a derived key DK:
|
||||
*
|
||||
* DK = T_1 || T_2 || ... || T_l<0..r-1>
|
||||
*
|
||||
* 5. Output the derived key DK.
|
||||
*
|
||||
* Note. The construction of the function F follows a "belt-and-
|
||||
* suspenders" approach. The iterates U_i are computed recursively to
|
||||
* remove a degree of parallelism from an opponent; they are exclusive-
|
||||
* ored together to reduce concerns about the recursion degenerating
|
||||
* into a small set of values.
|
||||
*
|
||||
*/
|
||||
|
||||
if (crypt_hmac_init(&hmac, hash, P, Plen))
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 1; (uint) i <= l; i++) {
|
||||
memset(T, 0, hLen);
|
||||
|
||||
for (u = 1; u <= c ; u++) {
|
||||
if (u == 1) {
|
||||
memcpy(tmp, S, Slen);
|
||||
tmp[Slen + 0] = (i & 0xff000000) >> 24;
|
||||
tmp[Slen + 1] = (i & 0x00ff0000) >> 16;
|
||||
tmp[Slen + 2] = (i & 0x0000ff00) >> 8;
|
||||
tmp[Slen + 3] = (i & 0x000000ff) >> 0;
|
||||
|
||||
if (crypt_hmac_write(hmac, tmp, tmplen))
|
||||
goto out;
|
||||
} else {
|
||||
if (crypt_hmac_write(hmac, U, hLen))
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (crypt_hmac_final(hmac, U, hLen))
|
||||
goto out;
|
||||
|
||||
for (k = 0; (uint) k < hLen; k++)
|
||||
T[k] ^= U[k];
|
||||
|
||||
if (perfcheck && __PBKDF2_performance) {
|
||||
rc = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (perfcheck)
|
||||
__PBKDF2_global_j++;
|
||||
}
|
||||
|
||||
memcpy(DK + (i - 1) * hLen, T, (uint) i == l ? r : hLen);
|
||||
}
|
||||
rc = 0;
|
||||
out:
|
||||
crypt_hmac_destroy(hmac);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int PBKDF2_HMAC(const char *hash,
|
||||
const char *password, size_t passwordLen,
|
||||
const char *salt, size_t saltLen, unsigned int iterations,
|
||||
char *dKey, size_t dKeyLen)
|
||||
{
|
||||
return pkcs5_pbkdf2(hash, password, passwordLen, salt, saltLen,
|
||||
iterations, (unsigned int)dKeyLen, dKey, 0);
|
||||
}
|
||||
|
||||
int PBKDF2_HMAC_ready(const char *hash)
|
||||
{
|
||||
if (crypt_hmac_size(hash) < 20)
|
||||
return -EINVAL;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void sigvtalarm(int foo __attribute__((unused)))
|
||||
{
|
||||
__PBKDF2_performance = __PBKDF2_global_j;
|
||||
}
|
||||
|
||||
/* This code benchmarks PBKDF2 and returns iterations/second using wth specified hash */
|
||||
int PBKDF2_performance_check(const char *hash, uint64_t *iter)
|
||||
{
|
||||
int timer_type, r;
|
||||
char buf;
|
||||
struct itimerval it;
|
||||
|
||||
if (__PBKDF2_global_j)
|
||||
return -EBUSY;
|
||||
|
||||
if (PBKDF2_HMAC_ready(hash) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
/* If crypto backend is not implemented in userspace,
|
||||
* but uses some kernel part, we must measure also time
|
||||
* spent in kernel. */
|
||||
if (crypt_backend_flags() & CRYPT_BACKEND_KERNEL) {
|
||||
timer_type = ITIMER_PROF;
|
||||
signal(SIGPROF,sigvtalarm);
|
||||
} else {
|
||||
timer_type = ITIMER_VIRTUAL;
|
||||
signal(SIGVTALRM,sigvtalarm);
|
||||
}
|
||||
|
||||
it.it_interval.tv_usec = 0;
|
||||
it.it_interval.tv_sec = 0;
|
||||
it.it_value.tv_usec = 0;
|
||||
it.it_value.tv_sec = 1;
|
||||
if (setitimer(timer_type, &it, NULL) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
r = pkcs5_pbkdf2(hash, "foo", 3, "bar", 3, ~(0U), 1, &buf, 1);
|
||||
|
||||
*iter = __PBKDF2_performance;
|
||||
__PBKDF2_global_j = 0;
|
||||
__PBKDF2_performance = 0;
|
||||
return r;
|
||||
}
|
||||
40
lib/luks1/pbkdf.h
Normal file
40
lib/luks1/pbkdf.h
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Implementation of Password-Based Cryptography as per PKCS#5
|
||||
* Copyright (C) 2002,2003 Simon Josefsson
|
||||
* Copyright (C) 2004 Free Software Foundation
|
||||
*
|
||||
* LUKS code
|
||||
* Copyright (C) 2004, Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2012, 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_CRYPTSETUP_LUKS_PBKDF_H
|
||||
#define INCLUDED_CRYPTSETUP_LUKS_PBKDF_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
int PBKDF2_HMAC(const char *hash,
|
||||
const char *password, size_t passwordLen,
|
||||
const char *salt, size_t saltLen, unsigned int iterations,
|
||||
char *dKey, size_t dKeyLen);
|
||||
|
||||
|
||||
int PBKDF2_performance_check(const char *hash, uint64_t *iter);
|
||||
int PBKDF2_HMAC_ready(const char *hash);
|
||||
|
||||
#endif
|
||||
34
lib/nls.h
Normal file
34
lib/nls.h
Normal file
@@ -0,0 +1,34 @@
|
||||
#ifndef CRYPTSETUP_NLS_H
|
||||
#define CRYPTSETUP_NLS_H
|
||||
|
||||
#ifndef LOCALEDIR
|
||||
#define LOCALEDIR "/usr/share/locale"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LOCALE_H
|
||||
# include <locale.h>
|
||||
#else
|
||||
# undef setlocale
|
||||
# define setlocale(Category, Locale) /* empty */
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_NLS
|
||||
# include <libintl.h>
|
||||
# define _(Text) gettext (Text)
|
||||
# ifdef gettext_noop
|
||||
# define N_(String) gettext_noop (String)
|
||||
# else
|
||||
# define N_(String) (String)
|
||||
# endif
|
||||
#else
|
||||
# undef bindtextdomain
|
||||
# define bindtextdomain(Domain, Directory) /* empty */
|
||||
# undef textdomain
|
||||
# define textdomain(Domain) /* empty */
|
||||
# define _(Text) (Text)
|
||||
# define N_(Text) (Text)
|
||||
# define ngettext(Singular, Plural, Count) \
|
||||
( (Count) == 1 ? (Singular) : (Plural) )
|
||||
#endif
|
||||
|
||||
#endif /* CRYPTSETUP_NLS_H */
|
||||
240
lib/random.c
Normal file
240
lib/random.c
Normal file
@@ -0,0 +1,240 @@
|
||||
/*
|
||||
* cryptsetup kernel RNG access functions
|
||||
*
|
||||
* Copyright (C) 2010-2012, 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
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "libcryptsetup.h"
|
||||
#include "internal.h"
|
||||
|
||||
static int random_initialised = 0;
|
||||
|
||||
#define URANDOM_DEVICE "/dev/urandom"
|
||||
static int urandom_fd = -1;
|
||||
|
||||
#define RANDOM_DEVICE "/dev/random"
|
||||
static int random_fd = -1;
|
||||
|
||||
/* Read random chunk - gathered data usually appears with this granularity */
|
||||
#define RANDOM_DEVICE_CHUNK 8
|
||||
|
||||
/* Timeout to print warning if no random data (entropy) */
|
||||
#define RANDOM_DEVICE_TIMEOUT 5
|
||||
|
||||
/* URANDOM_DEVICE access */
|
||||
static int _get_urandom(struct crypt_device *ctx __attribute__((unused)),
|
||||
char *buf, size_t len)
|
||||
{
|
||||
int r;
|
||||
size_t old_len = len;
|
||||
char *old_buf = buf;
|
||||
|
||||
assert(urandom_fd != -1);
|
||||
|
||||
while(len) {
|
||||
r = read(urandom_fd, buf, len);
|
||||
if (r == -1 && errno != EINTR)
|
||||
return -EINVAL;
|
||||
if (r > 0) {
|
||||
len -= r;
|
||||
buf += r;
|
||||
}
|
||||
}
|
||||
|
||||
assert(len == 0);
|
||||
assert((size_t)(buf - old_buf) == old_len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void _get_random_progress(struct crypt_device *ctx, int warn,
|
||||
size_t expected_len, size_t read_len)
|
||||
{
|
||||
if (warn)
|
||||
log_std(ctx,
|
||||
_("System is out of entropy while generating volume key.\n"
|
||||
"Please move mouse or type some text in another window "
|
||||
"to gather some random events.\n"));
|
||||
|
||||
log_std(ctx, _("Generating key (%d%% done).\n"),
|
||||
(int)((expected_len - read_len) * 100 / expected_len));
|
||||
}
|
||||
|
||||
/* RANDOM_DEVICE access */
|
||||
static int _get_random(struct crypt_device *ctx, char *buf, size_t len)
|
||||
{
|
||||
int r, warn_once = 1;
|
||||
size_t n, old_len = len;
|
||||
char *old_buf = buf;
|
||||
fd_set fds;
|
||||
struct timeval tv;
|
||||
|
||||
assert(random_fd != -1);
|
||||
|
||||
while (len) {
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(random_fd, &fds);
|
||||
|
||||
tv.tv_sec = RANDOM_DEVICE_TIMEOUT;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
r = select(random_fd + 1, &fds, NULL, NULL, &tv);
|
||||
if(r == -1)
|
||||
return -EINVAL;
|
||||
|
||||
if(!r) {
|
||||
_get_random_progress(ctx, warn_once, old_len, len);
|
||||
warn_once = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
do {
|
||||
n = RANDOM_DEVICE_CHUNK;
|
||||
if (len < RANDOM_DEVICE_CHUNK)
|
||||
n = len;
|
||||
|
||||
r = read(random_fd, buf, n);
|
||||
|
||||
if (r == -1 && errno == EINTR) {
|
||||
r = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* bogus read? */
|
||||
if(r > (int)n)
|
||||
return -EINVAL;
|
||||
|
||||
/* random device is opened with O_NONBLOCK, EAGAIN is expected */
|
||||
if (r == -1 && (errno != EAGAIN && errno != EWOULDBLOCK))
|
||||
return -EINVAL;
|
||||
|
||||
if (r > 0) {
|
||||
len -= r;
|
||||
buf += r;
|
||||
}
|
||||
} while (len && r > 0);
|
||||
}
|
||||
|
||||
assert(len == 0);
|
||||
assert((size_t)(buf - old_buf) == old_len);
|
||||
|
||||
if (!warn_once)
|
||||
_get_random_progress(ctx, 0, old_len, len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
/* Initialisation of both RNG file descriptors is mandatory */
|
||||
int crypt_random_init(struct crypt_device *ctx)
|
||||
{
|
||||
if (random_initialised)
|
||||
return 0;
|
||||
|
||||
/* Used for CRYPT_RND_NORMAL */
|
||||
if(urandom_fd == -1)
|
||||
urandom_fd = open(URANDOM_DEVICE, O_RDONLY);
|
||||
if(urandom_fd == -1)
|
||||
goto fail;
|
||||
|
||||
/* Used for CRYPT_RND_KEY */
|
||||
if(random_fd == -1)
|
||||
random_fd = open(RANDOM_DEVICE, O_RDONLY | O_NONBLOCK);
|
||||
if(random_fd == -1)
|
||||
goto fail;
|
||||
|
||||
random_initialised = 1;
|
||||
return 0;
|
||||
fail:
|
||||
crypt_random_exit();
|
||||
log_err(ctx, _("Fatal error during RNG initialisation.\n"));
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
int crypt_random_get(struct crypt_device *ctx, char *buf, size_t len, int quality)
|
||||
{
|
||||
int status, rng_type;
|
||||
|
||||
switch(quality) {
|
||||
case CRYPT_RND_NORMAL:
|
||||
status = _get_urandom(ctx, buf, len);
|
||||
break;
|
||||
case CRYPT_RND_SALT:
|
||||
if (crypt_fips_mode())
|
||||
status = crypt_backend_rng(buf, len, quality, 1);
|
||||
else
|
||||
status = _get_urandom(ctx, buf, len);
|
||||
break;
|
||||
case CRYPT_RND_KEY:
|
||||
if (crypt_fips_mode()) {
|
||||
status = crypt_backend_rng(buf, len, quality, 1);
|
||||
break;
|
||||
}
|
||||
rng_type = ctx ? crypt_get_rng_type(ctx) :
|
||||
crypt_random_default_key_rng();
|
||||
switch (rng_type) {
|
||||
case CRYPT_RNG_URANDOM:
|
||||
status = _get_urandom(ctx, buf, len);
|
||||
break;
|
||||
case CRYPT_RNG_RANDOM:
|
||||
status = _get_random(ctx, buf, len);
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
log_err(ctx, _("Unknown RNG quality requested.\n"));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (status)
|
||||
log_err(ctx, _("Error %d reading from RNG: %s\n"),
|
||||
errno, strerror(errno));
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void crypt_random_exit(void)
|
||||
{
|
||||
random_initialised = 0;
|
||||
|
||||
if(random_fd != -1) {
|
||||
(void)close(random_fd);
|
||||
random_fd = -1;
|
||||
}
|
||||
|
||||
if(urandom_fd != -1) {
|
||||
(void)close(urandom_fd);
|
||||
urandom_fd = -1;
|
||||
}
|
||||
}
|
||||
|
||||
int crypt_random_default_key_rng(void)
|
||||
{
|
||||
if (!strcmp(DEFAULT_RNG, RANDOM_DEVICE))
|
||||
return CRYPT_RNG_RANDOM;
|
||||
|
||||
if (!strcmp(DEFAULT_RNG, URANDOM_DEVICE))
|
||||
return CRYPT_RNG_URANDOM;
|
||||
|
||||
/* RNG misconfiguration is fatal */
|
||||
abort();
|
||||
}
|
||||
3201
lib/setup.c
3201
lib/setup.c
File diff suppressed because it is too large
Load Diff
739
lib/utils.c
739
lib/utils.c
@@ -1,3 +1,24 @@
|
||||
/*
|
||||
* utils - miscellaneous device utilities for cryptsetup
|
||||
*
|
||||
* Copyright (C) 2004, Christophe Saout <christophe@saout.de>
|
||||
* Copyright (C) 2004-2007, Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2012, 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
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
@@ -11,115 +32,35 @@
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <fcntl.h>
|
||||
#include <termios.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/resource.h>
|
||||
|
||||
#include "libcryptsetup.h"
|
||||
#include "internal.h"
|
||||
|
||||
|
||||
struct safe_allocation {
|
||||
size_t size;
|
||||
char data[1];
|
||||
};
|
||||
|
||||
static char *error=NULL;
|
||||
|
||||
void set_error_va(const char *fmt, va_list va)
|
||||
unsigned crypt_getpagesize(void)
|
||||
{
|
||||
|
||||
if(error) {
|
||||
free(error);
|
||||
error=NULL;
|
||||
}
|
||||
|
||||
if(!fmt) return;
|
||||
|
||||
if (vasprintf(&error, fmt, va) < 0) {
|
||||
free(error);
|
||||
error = NULL;
|
||||
}
|
||||
return (unsigned)sysconf(_SC_PAGESIZE);
|
||||
}
|
||||
|
||||
void set_error(const char *fmt, ...)
|
||||
static int get_alignment(int fd)
|
||||
{
|
||||
va_list va;
|
||||
int alignment = DEFAULT_MEM_ALIGNMENT;
|
||||
|
||||
va_start(va, fmt);
|
||||
set_error_va(fmt, va);
|
||||
va_end(va);
|
||||
#ifdef _PC_REC_XFER_ALIGN
|
||||
alignment = fpathconf(fd, _PC_REC_XFER_ALIGN);
|
||||
if (alignment < 0)
|
||||
alignment = DEFAULT_MEM_ALIGNMENT;
|
||||
#endif
|
||||
return alignment;
|
||||
}
|
||||
|
||||
const char *get_error(void)
|
||||
static void *aligned_malloc(void **base, int size, int alignment)
|
||||
{
|
||||
return error;
|
||||
}
|
||||
|
||||
void *safe_alloc(size_t size)
|
||||
{
|
||||
struct safe_allocation *alloc;
|
||||
|
||||
if (!size)
|
||||
return NULL;
|
||||
|
||||
alloc = malloc(size + offsetof(struct safe_allocation, data));
|
||||
if (!alloc)
|
||||
return NULL;
|
||||
|
||||
alloc->size = size;
|
||||
|
||||
return &alloc->data;
|
||||
}
|
||||
|
||||
void safe_free(void *data)
|
||||
{
|
||||
struct safe_allocation *alloc;
|
||||
|
||||
if (!data)
|
||||
return;
|
||||
|
||||
alloc = data - offsetof(struct safe_allocation, data);
|
||||
|
||||
memset(data, 0, alloc->size);
|
||||
|
||||
alloc->size = 0x55aa55aa;
|
||||
free(alloc);
|
||||
}
|
||||
|
||||
void *safe_realloc(void *data, size_t size)
|
||||
{
|
||||
void *new_data;
|
||||
|
||||
new_data = safe_alloc(size);
|
||||
|
||||
if (new_data && data) {
|
||||
struct safe_allocation *alloc;
|
||||
|
||||
alloc = data - offsetof(struct safe_allocation, data);
|
||||
|
||||
if (size > alloc->size)
|
||||
size = alloc->size;
|
||||
|
||||
memcpy(new_data, data, size);
|
||||
}
|
||||
|
||||
safe_free(data);
|
||||
return new_data;
|
||||
}
|
||||
|
||||
char *safe_strdup(const char *s)
|
||||
{
|
||||
char *s2 = safe_alloc(strlen(s) + 1);
|
||||
|
||||
if (!s2)
|
||||
return NULL;
|
||||
|
||||
return strcpy(s2, s);
|
||||
}
|
||||
|
||||
#ifdef HAVE_POSIX_MEMALIGN
|
||||
return posix_memalign(base, alignment, size) ? NULL : *base;
|
||||
#else
|
||||
/* Credits go to Michal's padlock patches for this alignment code */
|
||||
|
||||
static void *aligned_malloc(char **base, int size, int alignment)
|
||||
{
|
||||
char *ptr;
|
||||
|
||||
ptr = malloc(size + alignment);
|
||||
@@ -130,6 +71,24 @@ static void *aligned_malloc(char **base, int size, int alignment)
|
||||
ptr += alignment - ((long)(ptr) & (alignment - 1));
|
||||
}
|
||||
return ptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
int device_read_ahead(const char *dev, uint32_t *read_ahead)
|
||||
{
|
||||
int fd, r = 0;
|
||||
long read_ahead_long;
|
||||
|
||||
if ((fd = open(dev, O_RDONLY)) < 0)
|
||||
return 0;
|
||||
|
||||
r = ioctl(fd, BLKRAGET, &read_ahead_long) ? 0 : 1;
|
||||
close(fd);
|
||||
|
||||
if (r)
|
||||
*read_ahead = (uint32_t) read_ahead_long;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int sector_size(int fd)
|
||||
@@ -152,318 +111,416 @@ int sector_size_for_device(const char *device)
|
||||
return r;
|
||||
}
|
||||
|
||||
ssize_t write_blockwise(int fd, const void *orig_buf, size_t count)
|
||||
ssize_t write_blockwise(int fd, void *orig_buf, size_t count)
|
||||
{
|
||||
char *padbuf; char *padbuf_base;
|
||||
char *buf = (char *)orig_buf;
|
||||
int r = 0;
|
||||
int hangover; int solid; int bsize;
|
||||
void *hangover_buf, *hangover_buf_base = NULL;
|
||||
void *buf, *buf_base = NULL;
|
||||
int r, hangover, solid, bsize, alignment;
|
||||
ssize_t ret = -1;
|
||||
|
||||
if ((bsize = sector_size(fd)) < 0)
|
||||
return bsize;
|
||||
|
||||
hangover = count % bsize;
|
||||
solid = count - hangover;
|
||||
alignment = get_alignment(fd);
|
||||
|
||||
padbuf = aligned_malloc(&padbuf_base, bsize, bsize);
|
||||
if(padbuf == NULL) return -ENOMEM;
|
||||
if ((long)orig_buf & (alignment - 1)) {
|
||||
buf = aligned_malloc(&buf_base, count, alignment);
|
||||
if (!buf)
|
||||
goto out;
|
||||
memcpy(buf, orig_buf, count);
|
||||
} else
|
||||
buf = orig_buf;
|
||||
|
||||
while(solid) {
|
||||
memcpy(padbuf, buf, bsize);
|
||||
r = write(fd, padbuf, bsize);
|
||||
if(r < 0 || r != bsize) goto out;
|
||||
r = write(fd, buf, solid);
|
||||
if (r < 0 || r != solid)
|
||||
goto out;
|
||||
|
||||
solid -= bsize;
|
||||
buf += bsize;
|
||||
if (hangover) {
|
||||
hangover_buf = aligned_malloc(&hangover_buf_base, bsize, alignment);
|
||||
if (!hangover_buf)
|
||||
goto out;
|
||||
|
||||
r = read(fd, hangover_buf, bsize);
|
||||
if (r < 0 || r != bsize)
|
||||
goto out;
|
||||
|
||||
r = lseek(fd, -bsize, SEEK_CUR);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
memcpy(hangover_buf, (char*)buf + solid, hangover);
|
||||
|
||||
r = write(fd, hangover_buf, bsize);
|
||||
if (r < 0 || r != bsize)
|
||||
goto out;
|
||||
}
|
||||
if(hangover) {
|
||||
r = read(fd,padbuf,bsize);
|
||||
if(r < 0 || r != bsize) goto out;
|
||||
|
||||
lseek(fd,-bsize,SEEK_CUR);
|
||||
memcpy(padbuf,buf,hangover);
|
||||
|
||||
r = write(fd,padbuf, bsize);
|
||||
if(r < 0 || r != bsize) goto out;
|
||||
buf += hangover;
|
||||
}
|
||||
out:
|
||||
free(padbuf_base);
|
||||
return (buf-(char *)orig_buf)?(buf-(char *)orig_buf):r;
|
||||
|
||||
ret = count;
|
||||
out:
|
||||
free(hangover_buf_base);
|
||||
if (buf != orig_buf)
|
||||
free(buf_base);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ssize_t read_blockwise(int fd, void *orig_buf, size_t count) {
|
||||
char *padbuf; char *padbuf_base;
|
||||
char *buf = (char *)orig_buf;
|
||||
int r = 0;
|
||||
int step;
|
||||
int bsize;
|
||||
void *hangover_buf, *hangover_buf_base = NULL;
|
||||
void *buf, *buf_base = NULL;
|
||||
int r, hangover, solid, bsize, alignment;
|
||||
ssize_t ret = -1;
|
||||
|
||||
if ((bsize = sector_size(fd)) < 0)
|
||||
return bsize;
|
||||
|
||||
padbuf = aligned_malloc(&padbuf_base, bsize, bsize);
|
||||
if(padbuf == NULL) return -ENOMEM;
|
||||
hangover = count % bsize;
|
||||
solid = count - hangover;
|
||||
alignment = get_alignment(fd);
|
||||
|
||||
while(count) {
|
||||
r = read(fd,padbuf,bsize);
|
||||
if(r < 0 || r != bsize) {
|
||||
set_error("read failed in read_blockwise.\n");
|
||||
if ((long)orig_buf & (alignment - 1)) {
|
||||
buf = aligned_malloc(&buf_base, count, alignment);
|
||||
if (!buf)
|
||||
return -1;
|
||||
} else
|
||||
buf = orig_buf;
|
||||
|
||||
r = read(fd, buf, solid);
|
||||
if(r < 0 || r != solid)
|
||||
goto out;
|
||||
|
||||
if (hangover) {
|
||||
hangover_buf = aligned_malloc(&hangover_buf_base, bsize, alignment);
|
||||
if (!hangover_buf)
|
||||
goto out;
|
||||
}
|
||||
step = count<bsize?count:bsize;
|
||||
memcpy(buf,padbuf,step);
|
||||
buf += step;
|
||||
count -= step;
|
||||
r = read(fd, hangover_buf, bsize);
|
||||
if (r < 0 || r != bsize)
|
||||
goto out;
|
||||
|
||||
memcpy((char *)buf + solid, hangover_buf, hangover);
|
||||
}
|
||||
out:
|
||||
free(padbuf_base);
|
||||
return (buf-(char *)orig_buf)?(buf-(char *)orig_buf):r;
|
||||
ret = count;
|
||||
out:
|
||||
free(hangover_buf_base);
|
||||
if (buf != orig_buf) {
|
||||
memcpy(orig_buf, buf, count);
|
||||
free(buf_base);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* Combines llseek with blockwise write. write_blockwise can already deal with short writes
|
||||
* but we also need a function to deal with short writes at the start. But this information
|
||||
* is implicitly included in the read/write offset, which can not be set to non-aligned
|
||||
* is implicitly included in the read/write offset, which can not be set to non-aligned
|
||||
* boundaries. Hence, we combine llseek with write.
|
||||
*/
|
||||
ssize_t write_lseek_blockwise(int fd, char *buf, size_t count, off_t offset) {
|
||||
char *frontPadBuf;
|
||||
void *frontPadBuf_base = NULL;
|
||||
int r, bsize, frontHang;
|
||||
size_t innerCount = 0;
|
||||
ssize_t ret = -1;
|
||||
|
||||
ssize_t write_lseek_blockwise(int fd, const char *buf, size_t count, off_t offset) {
|
||||
int bsize = sector_size(fd);
|
||||
const char *orig_buf = buf;
|
||||
char frontPadBuf[bsize];
|
||||
int frontHang = offset % bsize;
|
||||
int r;
|
||||
int innerCount = count < bsize ? count : bsize;
|
||||
|
||||
if (bsize < 0)
|
||||
if ((bsize = sector_size(fd)) < 0)
|
||||
return bsize;
|
||||
|
||||
lseek(fd, offset - frontHang, SEEK_SET);
|
||||
if(offset % bsize) {
|
||||
r = read(fd,frontPadBuf,bsize);
|
||||
if(r < 0) return -1;
|
||||
frontHang = offset % bsize;
|
||||
|
||||
memcpy(frontPadBuf+frontHang, buf, innerCount);
|
||||
if (lseek(fd, offset - frontHang, SEEK_SET) < 0)
|
||||
goto out;
|
||||
|
||||
lseek(fd, offset - frontHang, SEEK_SET);
|
||||
r = write(fd,frontPadBuf,bsize);
|
||||
if(r < 0) return -1;
|
||||
if (frontHang) {
|
||||
frontPadBuf = aligned_malloc(&frontPadBuf_base,
|
||||
bsize, get_alignment(fd));
|
||||
if (!frontPadBuf)
|
||||
goto out;
|
||||
|
||||
r = read(fd, frontPadBuf, bsize);
|
||||
if (r < 0 || r != bsize)
|
||||
goto out;
|
||||
|
||||
innerCount = bsize - frontHang;
|
||||
if (innerCount > count)
|
||||
innerCount = count;
|
||||
|
||||
memcpy(frontPadBuf + frontHang, buf, innerCount);
|
||||
|
||||
if (lseek(fd, offset - frontHang, SEEK_SET) < 0)
|
||||
goto out;
|
||||
|
||||
r = write(fd, frontPadBuf, bsize);
|
||||
if (r < 0 || r != bsize)
|
||||
goto out;
|
||||
|
||||
buf += innerCount;
|
||||
count -= innerCount;
|
||||
}
|
||||
if(count <= 0) return buf - orig_buf;
|
||||
|
||||
return write_blockwise(fd, buf, count) + innerCount;
|
||||
ret = count ? write_blockwise(fd, buf, count) : 0;
|
||||
if (ret >= 0)
|
||||
ret += innerCount;
|
||||
out:
|
||||
free(frontPadBuf_base);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Password reading helpers */
|
||||
|
||||
static int untimed_read(int fd, char *pass, size_t maxlen)
|
||||
int device_ready(struct crypt_device *cd, const char *device, int mode)
|
||||
{
|
||||
ssize_t i;
|
||||
int devfd, r = 0;
|
||||
ssize_t s;
|
||||
struct stat st;
|
||||
char buf[512];
|
||||
|
||||
i = read(fd, pass, maxlen);
|
||||
if (i > 0) {
|
||||
pass[i-1] = '\0';
|
||||
i = 0;
|
||||
} else if (i == 0) { /* EOF */
|
||||
*pass = 0;
|
||||
i = -1;
|
||||
if(stat(device, &st) < 0) {
|
||||
log_err(cd, _("Device %s doesn't exist or access denied.\n"), device);
|
||||
return -EINVAL;
|
||||
}
|
||||
return i;
|
||||
|
||||
if (!S_ISBLK(st.st_mode))
|
||||
return -ENOTBLK;
|
||||
|
||||
log_dbg("Trying to open and read device %s.", device);
|
||||
devfd = open(device, mode | O_DIRECT | O_SYNC);
|
||||
if(devfd < 0) {
|
||||
log_err(cd, _("Cannot open device %s for %s%s access.\n"), device,
|
||||
(mode & O_EXCL) ? _("exclusive ") : "",
|
||||
(mode & O_RDWR) ? _("writable") : _("read-only"));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Try to read first sector */
|
||||
s = read_blockwise(devfd, buf, sizeof(buf));
|
||||
if (s < 0 || s != sizeof(buf)) {
|
||||
log_verbose(cd, _("Cannot read device %s.\n"), device);
|
||||
r = -EIO;
|
||||
}
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
close(devfd);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int timed_read(int fd, char *pass, size_t maxlen, long timeout)
|
||||
int device_size(const char *device, uint64_t *size)
|
||||
{
|
||||
struct timeval t;
|
||||
fd_set fds;
|
||||
int failed = -1;
|
||||
int devfd, r = 0;
|
||||
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(fd, &fds);
|
||||
t.tv_sec = timeout;
|
||||
t.tv_usec = 0;
|
||||
devfd = open(device, O_RDONLY);
|
||||
if(devfd == -1)
|
||||
return -EINVAL;
|
||||
|
||||
if (select(fd+1, &fds, NULL, NULL, &t) > 0)
|
||||
failed = untimed_read(fd, pass, maxlen);
|
||||
else
|
||||
set_error("Operation timed out");
|
||||
return failed;
|
||||
if (ioctl(devfd, BLKGETSIZE64, size) < 0)
|
||||
r = -EINVAL;
|
||||
|
||||
close(devfd);
|
||||
return r;
|
||||
}
|
||||
|
||||
static int interactive_pass(const char *prompt, char *pass, size_t maxlen,
|
||||
long timeout)
|
||||
static int get_device_infos(const char *device, enum devcheck device_check,
|
||||
int *readonly, uint64_t *size)
|
||||
{
|
||||
struct termios orig, tmp;
|
||||
int failed = -1;
|
||||
int infd = STDIN_FILENO, outfd;
|
||||
struct stat st;
|
||||
unsigned long size_small;
|
||||
int fd, r = -1;
|
||||
int flags = 0;
|
||||
|
||||
if (maxlen < 1)
|
||||
goto out_err;
|
||||
*readonly = 0;
|
||||
*size = 0;
|
||||
|
||||
/* Read and write to /dev/tty if available */
|
||||
if ((infd = outfd = open("/dev/tty", O_RDWR)) == -1) {
|
||||
infd = STDIN_FILENO;
|
||||
outfd = STDERR_FILENO;
|
||||
if (stat(device, &st) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
/* never wipe header on mounted device */
|
||||
if (device_check == DEV_EXCL && S_ISBLK(st.st_mode))
|
||||
flags |= O_EXCL;
|
||||
|
||||
/* Try to open read-write to check whether it is a read-only device */
|
||||
fd = open(device, O_RDWR | flags);
|
||||
if (fd == -1 && errno == EROFS) {
|
||||
*readonly = 1;
|
||||
fd = open(device, O_RDONLY | flags);
|
||||
}
|
||||
|
||||
if (tcgetattr(infd, &orig)) {
|
||||
set_error("Unable to get terminal");
|
||||
goto out_err;
|
||||
if (fd == -1 && device_check == DEV_EXCL && errno == EBUSY)
|
||||
return -EBUSY;
|
||||
|
||||
if (fd == -1)
|
||||
return -EINVAL;
|
||||
|
||||
/* If the device can be opened read-write, i.e. readonly is still 0, then
|
||||
* check whether BKROGET says that it is read-only. E.g. read-only loop
|
||||
* devices may be openend read-write but are read-only according to BLKROGET
|
||||
*/
|
||||
if (*readonly == 0 && (r = ioctl(fd, BLKROGET, readonly)) < 0)
|
||||
goto out;
|
||||
|
||||
if (ioctl(fd, BLKGETSIZE64, size) >= 0) {
|
||||
*size >>= SECTOR_SHIFT;
|
||||
r = 0;
|
||||
goto out;
|
||||
}
|
||||
memcpy(&tmp, &orig, sizeof(tmp));
|
||||
tmp.c_lflag &= ~ECHO;
|
||||
|
||||
if (write(outfd, prompt, strlen(prompt)) < 0)
|
||||
goto out_err;
|
||||
if (ioctl(fd, BLKGETSIZE, &size_small) >= 0) {
|
||||
*size = (uint64_t)size_small;
|
||||
r = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
tcsetattr(infd, TCSAFLUSH, &tmp);
|
||||
if (timeout)
|
||||
failed = timed_read(infd, pass, maxlen, timeout);
|
||||
else
|
||||
failed = untimed_read(infd, pass, maxlen);
|
||||
tcsetattr(infd, TCSAFLUSH, &orig);
|
||||
|
||||
out_err:
|
||||
if (!failed)
|
||||
(void)write(outfd, "\n", 1);
|
||||
if (infd != STDIN_FILENO)
|
||||
close(infd);
|
||||
return failed;
|
||||
r = -EINVAL;
|
||||
out:
|
||||
close(fd);
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* Password reading behaviour matrix of get_key
|
||||
*
|
||||
* p v n h
|
||||
* -----------------+---+---+---+---
|
||||
* interactive | Y | Y | Y | Inf
|
||||
* from fd | N | N | Y | Inf
|
||||
* from binary file | N | N | N | Inf or options->key_size
|
||||
*
|
||||
* Legend: p..prompt, v..can verify, n..newline-stop, h..read horizon
|
||||
*
|
||||
* Note: --key-file=- is interpreted as a read from a binary file (stdin)
|
||||
*
|
||||
* Returns true when more keys are available (that is when password
|
||||
* reading can be retried as for interactive terminals).
|
||||
*/
|
||||
|
||||
int get_key(char *prompt, char **key, unsigned int *passLen, int key_size,
|
||||
const char *key_file, int passphrase_fd, int timeout, int how2verify)
|
||||
int device_check_and_adjust(struct crypt_device *cd,
|
||||
const char *device,
|
||||
enum devcheck device_check,
|
||||
uint64_t *size,
|
||||
uint64_t *offset,
|
||||
uint32_t *flags)
|
||||
{
|
||||
int fd;
|
||||
const int verify = how2verify & CRYPT_FLAG_VERIFY;
|
||||
const int verify_if_possible = how2verify & CRYPT_FLAG_VERIFY_IF_POSSIBLE;
|
||||
char *pass = NULL;
|
||||
int newline_stop;
|
||||
int read_horizon;
|
||||
int r, real_readonly;
|
||||
uint64_t real_size;
|
||||
|
||||
if(key_file && !strcmp(key_file, "-")) {
|
||||
/* Allow binary reading from stdin */
|
||||
fd = passphrase_fd;
|
||||
newline_stop = 0;
|
||||
read_horizon = 0;
|
||||
} else if (key_file) {
|
||||
fd = open(key_file, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
char buf[128];
|
||||
set_error("Error opening key file: %s",
|
||||
strerror_r(errno, buf, 128));
|
||||
goto out_err;
|
||||
}
|
||||
newline_stop = 0;
|
||||
if (!device)
|
||||
return -ENOTBLK;
|
||||
|
||||
/* This can either be 0 (LUKS) or the actually number
|
||||
* of key bytes (default or passed by -s) */
|
||||
read_horizon = key_size;
|
||||
} else {
|
||||
fd = passphrase_fd;
|
||||
newline_stop = 1;
|
||||
read_horizon = 0; /* Infinite, if read from terminal or fd */
|
||||
r = get_device_infos(device, device_check, &real_readonly, &real_size);
|
||||
if (r < 0) {
|
||||
if (r == -EBUSY)
|
||||
log_err(cd, _("Cannot use device %s which is in use "
|
||||
"(already mapped or mounted).\n"),
|
||||
device);
|
||||
else
|
||||
log_err(cd, _("Cannot get info about device %s.\n"),
|
||||
device);
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Interactive case */
|
||||
if(isatty(fd)) {
|
||||
int i;
|
||||
|
||||
pass = safe_alloc(512);
|
||||
if (!pass || (i = interactive_pass(prompt, pass, 512, timeout))) {
|
||||
set_error("Error reading passphrase");
|
||||
goto out_err;
|
||||
}
|
||||
if (verify || verify_if_possible) {
|
||||
char pass_verify[512];
|
||||
i = interactive_pass("Verify passphrase: ", pass_verify, sizeof(pass_verify), timeout);
|
||||
if (i || strcmp(pass, pass_verify) != 0) {
|
||||
set_error("Passphrases do not match");
|
||||
goto out_err;
|
||||
}
|
||||
memset(pass_verify, 0, sizeof(pass_verify));
|
||||
}
|
||||
*passLen = strlen(pass);
|
||||
*key = pass;
|
||||
} else {
|
||||
/*
|
||||
* This is either a fd-input or a file, in neither case we can verify the input,
|
||||
* however we don't stop on new lines if it's a binary file.
|
||||
*/
|
||||
int buflen, i;
|
||||
|
||||
if(verify) {
|
||||
set_error("Can't do passphrase verification on non-tty inputs");
|
||||
goto out_err;
|
||||
}
|
||||
/* The following for control loop does an exhausting
|
||||
* read on the key material file, if requested with
|
||||
* key_size == 0, as it's done by LUKS. However, we
|
||||
* should warn the user, if it's a non-regular file,
|
||||
* such as /dev/random, because in this case, the loop
|
||||
* will read forever.
|
||||
*/
|
||||
if(key_file && strcmp(key_file, "-") && read_horizon == 0) {
|
||||
struct stat st;
|
||||
if(stat(key_file, &st) < 0) {
|
||||
set_error("Can't stat key file");
|
||||
goto out_err;
|
||||
}
|
||||
if(!S_ISREG(st.st_mode)) {
|
||||
// set_error("Can't do exhausting read on non regular files");
|
||||
// goto out_err;
|
||||
fprintf(stderr,"Warning: exhausting read requested, but key file is not a regular file, function might never return.\n");
|
||||
}
|
||||
}
|
||||
buflen = 0;
|
||||
for(i = 0; read_horizon == 0 || i < read_horizon; i++) {
|
||||
if(i >= buflen - 1) {
|
||||
buflen += 128;
|
||||
pass = safe_realloc(pass, buflen);
|
||||
if (!pass) {
|
||||
set_error("Not enough memory while "
|
||||
"reading passphrase");
|
||||
goto out_err;
|
||||
}
|
||||
}
|
||||
if(read(fd, pass + i, 1) != 1 || (newline_stop && pass[i] == '\n'))
|
||||
break;
|
||||
}
|
||||
if(key_file)
|
||||
close(fd);
|
||||
pass[i] = 0;
|
||||
*key = pass;
|
||||
*passLen = i;
|
||||
if (*offset >= real_size) {
|
||||
log_err(cd, _("Requested offset is beyond real size of device %s.\n"),
|
||||
device);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return isatty(fd); /* Return true, when password reading can be tried on interactive fds */
|
||||
if (!*size) {
|
||||
*size = real_size;
|
||||
if (!*size) {
|
||||
log_err(cd, _("Device %s has zero size.\n"), device);
|
||||
return -ENOTBLK;
|
||||
}
|
||||
*size -= *offset;
|
||||
}
|
||||
|
||||
out_err:
|
||||
if(pass)
|
||||
safe_free(pass);
|
||||
*key = NULL;
|
||||
*passLen = 0;
|
||||
/* in case of size is set by parameter */
|
||||
if ((real_size - *offset) < *size) {
|
||||
log_dbg("Device %s: offset = %" PRIu64 " requested size = %" PRIu64
|
||||
", backing device size = %" PRIu64,
|
||||
device, *offset, *size, real_size);
|
||||
log_err(cd, _("Device %s is too small.\n"), device);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (real_readonly)
|
||||
*flags |= CRYPT_ACTIVATE_READONLY;
|
||||
|
||||
log_dbg("Calculated device size is %" PRIu64 " sectors (%s), offset %" PRIu64 ".",
|
||||
*size, real_readonly ? "RO" : "RW", *offset);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* MEMLOCK */
|
||||
#define DEFAULT_PROCESS_PRIORITY -18
|
||||
|
||||
static int _priority;
|
||||
static int _memlock_count = 0;
|
||||
|
||||
// return 1 if memory is locked
|
||||
int crypt_memlock_inc(struct crypt_device *ctx)
|
||||
{
|
||||
if (!_memlock_count++) {
|
||||
log_dbg("Locking memory.");
|
||||
if (mlockall(MCL_CURRENT | MCL_FUTURE) == -1) {
|
||||
log_err(ctx, _("WARNING!!! Possibly insecure memory. Are you root?\n"));
|
||||
_memlock_count--;
|
||||
return 0;
|
||||
}
|
||||
errno = 0;
|
||||
if (((_priority = getpriority(PRIO_PROCESS, 0)) == -1) && errno)
|
||||
log_err(ctx, _("Cannot get process priority.\n"));
|
||||
else
|
||||
if (setpriority(PRIO_PROCESS, 0, DEFAULT_PROCESS_PRIORITY))
|
||||
log_err(ctx, _("setpriority %d failed: %s\n"),
|
||||
DEFAULT_PROCESS_PRIORITY, strerror(errno));
|
||||
}
|
||||
return _memlock_count ? 1 : 0;
|
||||
}
|
||||
|
||||
int crypt_memlock_dec(struct crypt_device *ctx)
|
||||
{
|
||||
if (_memlock_count && (!--_memlock_count)) {
|
||||
log_dbg("Unlocking memory.");
|
||||
if (munlockall() == -1)
|
||||
log_err(ctx, _("Cannot unlock memory.\n"));
|
||||
if (setpriority(PRIO_PROCESS, 0, _priority))
|
||||
log_err(ctx, _("setpriority %d failed: %s\n"), _priority, strerror(errno));
|
||||
}
|
||||
return _memlock_count ? 1 : 0;
|
||||
}
|
||||
|
||||
/* DEVICE TOPOLOGY */
|
||||
|
||||
/* block device topology ioctls, introduced in 2.6.32 */
|
||||
#ifndef BLKIOMIN
|
||||
#define BLKIOMIN _IO(0x12,120)
|
||||
#define BLKIOOPT _IO(0x12,121)
|
||||
#define BLKALIGNOFF _IO(0x12,122)
|
||||
#endif
|
||||
|
||||
void get_topology_alignment(const char *device,
|
||||
unsigned long *required_alignment, /* bytes */
|
||||
unsigned long *alignment_offset, /* bytes */
|
||||
unsigned long default_alignment)
|
||||
{
|
||||
int dev_alignment_offset = 0;
|
||||
unsigned int min_io_size = 0, opt_io_size = 0;
|
||||
unsigned long temp_alignment = 0;
|
||||
int fd;
|
||||
|
||||
*required_alignment = default_alignment;
|
||||
*alignment_offset = 0;
|
||||
|
||||
fd = open(device, O_RDONLY);
|
||||
if (fd == -1)
|
||||
return;
|
||||
|
||||
/* minimum io size */
|
||||
if (ioctl(fd, BLKIOMIN, &min_io_size) == -1) {
|
||||
log_dbg("Topology info for %s not supported, using default offset %lu bytes.",
|
||||
device, default_alignment);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* optimal io size */
|
||||
if (ioctl(fd, BLKIOOPT, &opt_io_size) == -1)
|
||||
opt_io_size = min_io_size;
|
||||
|
||||
/* alignment offset, bogus -1 means misaligned/unknown */
|
||||
if (ioctl(fd, BLKALIGNOFF, &dev_alignment_offset) == -1 || dev_alignment_offset < 0)
|
||||
dev_alignment_offset = 0;
|
||||
*alignment_offset = (unsigned long)dev_alignment_offset;
|
||||
|
||||
temp_alignment = (unsigned long)min_io_size;
|
||||
|
||||
if (temp_alignment < (unsigned long)opt_io_size)
|
||||
temp_alignment = (unsigned long)opt_io_size;
|
||||
|
||||
/* If calculated alignment is multiple of default, keep default */
|
||||
if (temp_alignment && (default_alignment % temp_alignment))
|
||||
*required_alignment = temp_alignment;
|
||||
|
||||
log_dbg("Topology: IO (%u/%u), offset = %lu; Required alignment is %lu bytes.",
|
||||
min_io_size, opt_io_size, *alignment_offset, *required_alignment);
|
||||
out:
|
||||
(void)close(fd);
|
||||
}
|
||||
|
||||
489
lib/utils_crypt.c
Normal file
489
lib/utils_crypt.c
Normal file
@@ -0,0 +1,489 @@
|
||||
/*
|
||||
* utils_crypt - cipher utilities for cryptsetup
|
||||
*
|
||||
* Copyright (C) 2004-2007, Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2012, 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
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <termios.h>
|
||||
|
||||
#include "libcryptsetup.h"
|
||||
#include "nls.h"
|
||||
#include "utils_crypt.h"
|
||||
|
||||
#define log_dbg(x) crypt_log(NULL, CRYPT_LOG_DEBUG, x)
|
||||
#define log_err(cd, x) crypt_log(cd, CRYPT_LOG_ERROR, x)
|
||||
|
||||
struct safe_allocation {
|
||||
size_t size;
|
||||
char data[0];
|
||||
};
|
||||
|
||||
int crypt_parse_name_and_mode(const char *s, char *cipher, int *key_nums,
|
||||
char *cipher_mode)
|
||||
{
|
||||
if (sscanf(s, "%" MAX_CIPHER_LEN_STR "[^-]-%" MAX_CIPHER_LEN_STR "s",
|
||||
cipher, cipher_mode) == 2) {
|
||||
if (!strcmp(cipher_mode, "plain"))
|
||||
strncpy(cipher_mode, "cbc-plain", 10);
|
||||
if (key_nums) {
|
||||
char *tmp = strchr(cipher, ':');
|
||||
*key_nums = tmp ? atoi(++tmp) : 1;
|
||||
if (!*key_nums)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Short version for "empty" cipher */
|
||||
if (!strcmp(s, "null")) {
|
||||
strncpy(cipher, "cipher_null", MAX_CIPHER_LEN);
|
||||
strncpy(cipher_mode, "ecb", 9);
|
||||
if (key_nums)
|
||||
*key_nums = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (sscanf(s, "%" MAX_CIPHER_LEN_STR "[^-]", cipher) == 1) {
|
||||
strncpy(cipher_mode, "cbc-plain", 10);
|
||||
if (key_nums)
|
||||
*key_nums = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* safe allocations */
|
||||
void *crypt_safe_alloc(size_t size)
|
||||
{
|
||||
struct safe_allocation *alloc;
|
||||
|
||||
if (!size)
|
||||
return NULL;
|
||||
|
||||
alloc = malloc(size + offsetof(struct safe_allocation, data));
|
||||
if (!alloc)
|
||||
return NULL;
|
||||
|
||||
alloc->size = size;
|
||||
|
||||
return &alloc->data;
|
||||
}
|
||||
|
||||
void crypt_safe_free(void *data)
|
||||
{
|
||||
struct safe_allocation *alloc;
|
||||
|
||||
if (!data)
|
||||
return;
|
||||
|
||||
alloc = (struct safe_allocation *)
|
||||
((char *)data - offsetof(struct safe_allocation, data));
|
||||
|
||||
memset(data, 0, alloc->size);
|
||||
|
||||
alloc->size = 0x55aa55aa;
|
||||
free(alloc);
|
||||
}
|
||||
|
||||
void *crypt_safe_realloc(void *data, size_t size)
|
||||
{
|
||||
struct safe_allocation *alloc;
|
||||
void *new_data;
|
||||
|
||||
new_data = crypt_safe_alloc(size);
|
||||
|
||||
if (new_data && data) {
|
||||
|
||||
alloc = (struct safe_allocation *)
|
||||
((char *)data - offsetof(struct safe_allocation, data));
|
||||
|
||||
if (size > alloc->size)
|
||||
size = alloc->size;
|
||||
|
||||
memcpy(new_data, data, size);
|
||||
}
|
||||
|
||||
crypt_safe_free(data);
|
||||
return new_data;
|
||||
}
|
||||
|
||||
/* Password reading helpers */
|
||||
static int untimed_read(int fd, char *pass, size_t maxlen)
|
||||
{
|
||||
ssize_t i;
|
||||
|
||||
i = read(fd, pass, maxlen);
|
||||
if (i > 0) {
|
||||
pass[i-1] = '\0';
|
||||
i = 0;
|
||||
} else if (i == 0) { /* EOF */
|
||||
*pass = 0;
|
||||
i = -1;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
static int timed_read(int fd, char *pass, size_t maxlen, long timeout)
|
||||
{
|
||||
struct timeval t;
|
||||
fd_set fds;
|
||||
int failed = -1;
|
||||
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(fd, &fds);
|
||||
t.tv_sec = timeout;
|
||||
t.tv_usec = 0;
|
||||
|
||||
if (select(fd+1, &fds, NULL, NULL, &t) > 0)
|
||||
failed = untimed_read(fd, pass, maxlen);
|
||||
|
||||
return failed;
|
||||
}
|
||||
|
||||
static int interactive_pass(const char *prompt, char *pass, size_t maxlen,
|
||||
long timeout)
|
||||
{
|
||||
struct termios orig, tmp;
|
||||
int failed = -1;
|
||||
int infd = STDIN_FILENO, outfd;
|
||||
|
||||
if (maxlen < 1)
|
||||
goto out_err;
|
||||
|
||||
/* Read and write to /dev/tty if available */
|
||||
if ((infd = outfd = open("/dev/tty", O_RDWR)) == -1) {
|
||||
infd = STDIN_FILENO;
|
||||
outfd = STDERR_FILENO;
|
||||
}
|
||||
|
||||
if (tcgetattr(infd, &orig))
|
||||
goto out_err;
|
||||
|
||||
memcpy(&tmp, &orig, sizeof(tmp));
|
||||
tmp.c_lflag &= ~ECHO;
|
||||
|
||||
if (prompt && write(outfd, prompt, strlen(prompt)) < 0)
|
||||
goto out_err;
|
||||
|
||||
tcsetattr(infd, TCSAFLUSH, &tmp);
|
||||
if (timeout)
|
||||
failed = timed_read(infd, pass, maxlen, timeout);
|
||||
else
|
||||
failed = untimed_read(infd, pass, maxlen);
|
||||
tcsetattr(infd, TCSAFLUSH, &orig);
|
||||
|
||||
out_err:
|
||||
if (!failed && write(outfd, "\n", 1)) {};
|
||||
|
||||
if (infd != STDIN_FILENO)
|
||||
close(infd);
|
||||
return failed;
|
||||
}
|
||||
|
||||
static int crypt_get_key_tty(const char *prompt,
|
||||
char **key, size_t *key_size,
|
||||
int timeout, int verify,
|
||||
struct crypt_device *cd)
|
||||
{
|
||||
int key_size_max = DEFAULT_PASSPHRASE_SIZE_MAX;
|
||||
int r = -EINVAL;
|
||||
char *pass = NULL, *pass_verify = NULL;
|
||||
|
||||
log_dbg("Interactive passphrase entry requested.");
|
||||
|
||||
pass = crypt_safe_alloc(key_size_max + 1);
|
||||
if (!pass) {
|
||||
log_err(cd, _("Out of memory while reading passphrase.\n"));
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (interactive_pass(prompt, pass, key_size_max, timeout)) {
|
||||
log_err(cd, _("Error reading passphrase from terminal.\n"));
|
||||
goto out_err;
|
||||
}
|
||||
pass[key_size_max] = '\0';
|
||||
|
||||
if (verify) {
|
||||
pass_verify = crypt_safe_alloc(key_size_max);
|
||||
if (!pass_verify) {
|
||||
log_err(cd, _("Out of memory while reading passphrase.\n"));
|
||||
r = -ENOMEM;
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
if (interactive_pass(_("Verify passphrase: "),
|
||||
pass_verify, key_size_max, timeout)) {
|
||||
log_err(cd, _("Error reading passphrase from terminal.\n"));
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
if (strncmp(pass, pass_verify, key_size_max)) {
|
||||
log_err(cd, _("Passphrases do not match.\n"));
|
||||
r = -EPERM;
|
||||
goto out_err;
|
||||
}
|
||||
}
|
||||
|
||||
*key = pass;
|
||||
*key_size = strlen(pass);
|
||||
r = 0;
|
||||
out_err:
|
||||
crypt_safe_free(pass_verify);
|
||||
if (r)
|
||||
crypt_safe_free(pass);
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* Note: --key-file=- is interpreted as a read from a binary file (stdin)
|
||||
* key_size_max == 0 means detect maximum according to input type (tty/file)
|
||||
* timeout and verify options only applies to tty input
|
||||
*/
|
||||
int crypt_get_key(const char *prompt,
|
||||
char **key, size_t *key_size,
|
||||
size_t keyfile_offset, size_t keyfile_size_max,
|
||||
const char *key_file, int timeout, int verify,
|
||||
struct crypt_device *cd)
|
||||
{
|
||||
int fd, regular_file, read_stdin, char_read, unlimited_read = 0;
|
||||
int r = -EINVAL;
|
||||
char *pass = NULL, tmp;
|
||||
size_t buflen, i, file_read_size;
|
||||
struct stat st;
|
||||
|
||||
*key = NULL;
|
||||
*key_size = 0;
|
||||
|
||||
/* Passphrase read from stdin? */
|
||||
read_stdin = (!key_file || !strcmp(key_file, "-")) ? 1 : 0;
|
||||
|
||||
if (read_stdin && isatty(STDIN_FILENO)) {
|
||||
if (keyfile_offset) {
|
||||
log_err(cd, _("Cannot use offset with terminal input.\n"));
|
||||
return -EINVAL;
|
||||
}
|
||||
return crypt_get_key_tty(prompt, key, key_size, timeout, verify, cd);
|
||||
}
|
||||
|
||||
if (read_stdin)
|
||||
log_dbg("STDIN descriptor passphrase entry requested.");
|
||||
else
|
||||
log_dbg("File descriptor passphrase entry requested.");
|
||||
|
||||
/* If not requsted otherwise, we limit input to prevent memory exhaustion */
|
||||
if (keyfile_size_max == 0) {
|
||||
keyfile_size_max = DEFAULT_KEYFILE_SIZE_MAXKB * 1024;
|
||||
unlimited_read = 1;
|
||||
}
|
||||
|
||||
fd = read_stdin ? STDIN_FILENO : open(key_file, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
log_err(cd, _("Failed to open key file.\n"));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* use 4k for buffer (page divisor but avoid huge pages) */
|
||||
buflen = 4096 - sizeof(struct safe_allocation);
|
||||
regular_file = 0;
|
||||
if(!read_stdin) {
|
||||
if(stat(key_file, &st) < 0) {
|
||||
log_err(cd, _("Failed to stat key file.\n"));
|
||||
goto out_err;
|
||||
}
|
||||
if(S_ISREG(st.st_mode)) {
|
||||
regular_file = 1;
|
||||
file_read_size = (size_t)st.st_size;
|
||||
|
||||
if (keyfile_offset > file_read_size) {
|
||||
log_err(cd, _("Cannot seek to requested keyfile offset.\n"));
|
||||
goto out_err;
|
||||
}
|
||||
file_read_size -= keyfile_offset;
|
||||
|
||||
/* known keyfile size, alloc it in one step */
|
||||
if (file_read_size >= keyfile_size_max)
|
||||
buflen = keyfile_size_max;
|
||||
else if (file_read_size)
|
||||
buflen = file_read_size;
|
||||
}
|
||||
}
|
||||
|
||||
pass = crypt_safe_alloc(buflen);
|
||||
if (!pass) {
|
||||
log_err(cd, _("Out of memory while reading passphrase.\n"));
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
/* Discard keyfile_offset bytes on input */
|
||||
for(i = 0; i < keyfile_offset; i++)
|
||||
if (read(fd, &tmp, 1) != 1) {
|
||||
log_err(cd, _("Cannot seek to requested keyfile offset.\n"));
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
for(i = 0; i < keyfile_size_max; i++) {
|
||||
if(i == buflen) {
|
||||
buflen += 4096;
|
||||
pass = crypt_safe_realloc(pass, buflen);
|
||||
if (!pass) {
|
||||
log_err(cd, _("Out of memory while reading passphrase.\n"));
|
||||
r = -ENOMEM;
|
||||
goto out_err;
|
||||
}
|
||||
}
|
||||
|
||||
char_read = read(fd, &pass[i], 1);
|
||||
if (char_read < 0) {
|
||||
log_err(cd, _("Error reading passphrase.\n"));
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
/* Stop on newline only if not requested read from keyfile */
|
||||
if(char_read == 0 || (!key_file && pass[i] == '\n'))
|
||||
break;
|
||||
}
|
||||
|
||||
/* Fail if piped input dies reading nothing */
|
||||
if(!i && !regular_file) {
|
||||
log_dbg("Nothing read on input.");
|
||||
r = -EPIPE;
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
/* Fail if we exceeded internal default (no specified size) */
|
||||
if (unlimited_read && i == keyfile_size_max) {
|
||||
log_err(cd, _("Maximum keyfile size exceeded.\n"));
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
if (!unlimited_read && i != keyfile_size_max) {
|
||||
log_err(cd, _("Cannot read requested amount of data.\n"));
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
*key = pass;
|
||||
*key_size = i;
|
||||
r = 0;
|
||||
out_err:
|
||||
if(fd != STDIN_FILENO)
|
||||
close(fd);
|
||||
|
||||
if (r)
|
||||
crypt_safe_free(pass);
|
||||
return r;
|
||||
}
|
||||
|
||||
ssize_t crypt_hex_to_bytes(const char *hex, char **result, int safe_alloc)
|
||||
{
|
||||
char buf[3] = "xx\0", *endp, *bytes;
|
||||
size_t i, len;
|
||||
|
||||
len = strlen(hex);
|
||||
if (len % 2)
|
||||
return -EINVAL;
|
||||
len /= 2;
|
||||
|
||||
bytes = safe_alloc ? crypt_safe_alloc(len) : malloc(len);
|
||||
if (!bytes)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
memcpy(buf, &hex[i * 2], 2);
|
||||
bytes[i] = strtoul(buf, &endp, 16);
|
||||
if (endp != &buf[2]) {
|
||||
safe_alloc ? crypt_safe_free(bytes) : free(bytes);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
*result = bytes;
|
||||
return i;
|
||||
}
|
||||
|
||||
/*
|
||||
* Device size string parsing, suffixes:
|
||||
* s|S - 512 bytes sectors
|
||||
* k |K |m |M |g |G |t |T - 1024 base
|
||||
* kiB|KiB|miB|MiB|giB|GiB|tiB|TiB - 1024 base
|
||||
* kb |KB |mM |MB |gB |GB |tB |TB - 1000 base
|
||||
*/
|
||||
int crypt_string_to_size(struct crypt_device *cd, const char *s, uint64_t *size)
|
||||
{
|
||||
char *endp = NULL;
|
||||
size_t len;
|
||||
uint64_t mult_base, mult, tmp;
|
||||
|
||||
*size = strtoull(s, &endp, 10);
|
||||
if (!isdigit(s[0]) ||
|
||||
(errno == ERANGE && *size == ULLONG_MAX) ||
|
||||
(errno != 0 && *size == 0))
|
||||
return -EINVAL;
|
||||
|
||||
if (!endp || !*endp)
|
||||
return 0;
|
||||
|
||||
len = strlen(endp);
|
||||
/* Allow "B" and "iB" suffixes */
|
||||
if (len > 3 ||
|
||||
(len == 3 && (endp[1] != 'i' || endp[2] != 'B')) ||
|
||||
(len == 2 && endp[1] != 'B'))
|
||||
return -EINVAL;
|
||||
|
||||
if (len == 1 || len == 3)
|
||||
mult_base = 1024;
|
||||
else
|
||||
mult_base = 1000;
|
||||
|
||||
mult = 1;
|
||||
switch (endp[0]) {
|
||||
case 's':
|
||||
case 'S': mult = 512;
|
||||
break;
|
||||
case 't':
|
||||
case 'T': mult *= mult_base;
|
||||
case 'g':
|
||||
case 'G': mult *= mult_base;
|
||||
case 'm':
|
||||
case 'M': mult *= mult_base;
|
||||
case 'k':
|
||||
case 'K': mult *= mult_base;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
tmp = *size * mult;
|
||||
if ((tmp / *size) != mult) {
|
||||
log_dbg("Device size overflow.");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
*size = tmp;
|
||||
return 0;
|
||||
}
|
||||
49
lib/utils_crypt.h
Normal file
49
lib/utils_crypt.h
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* utils_crypt - cipher utilities for cryptsetup
|
||||
*
|
||||
* Copyright (C) 2004-2007, Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2012, 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
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _UTILS_CRYPT_H
|
||||
#define _UTILS_CRYPT_H
|
||||
|
||||
#include <unistd.h>
|
||||
#include "config.h"
|
||||
|
||||
#define MAX_CIPHER_LEN 32
|
||||
#define MAX_CIPHER_LEN_STR "32"
|
||||
|
||||
struct crypt_device;
|
||||
|
||||
int crypt_parse_name_and_mode(const char *s, char *cipher,
|
||||
int *key_nums, char *cipher_mode);
|
||||
|
||||
int crypt_get_key(const char *prompt,
|
||||
char **key, size_t *key_size,
|
||||
size_t keyfile_offset, size_t keyfile_size_max,
|
||||
const char *key_file,
|
||||
int timeout, int verify,
|
||||
struct crypt_device *cd);
|
||||
|
||||
void *crypt_safe_alloc(size_t size);
|
||||
void crypt_safe_free(void *data);
|
||||
void *crypt_safe_realloc(void *data, size_t size);
|
||||
|
||||
ssize_t crypt_hex_to_bytes(const char *hex, char **result, int safe_alloc);
|
||||
int crypt_string_to_size(struct crypt_device *cd, const char *s, uint64_t *size);
|
||||
|
||||
#endif /* _UTILS_CRYPT_H */
|
||||
268
lib/utils_devpath.c
Normal file
268
lib/utils_devpath.c
Normal file
@@ -0,0 +1,268 @@
|
||||
/*
|
||||
* devname - search for device name
|
||||
*
|
||||
* Copyright (C) 2004, Christophe Saout <christophe@saout.de>
|
||||
* Copyright (C) 2004-2007, Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2012, 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
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <dirent.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include "utils_dm.h"
|
||||
|
||||
char *crypt_lookup_dev(const char *dev_id);
|
||||
int crypt_sysfs_check_crypt_segment(const char *device, uint64_t offset, uint64_t size);
|
||||
int crypt_sysfs_get_rotational(int major, int minor, int *rotational);
|
||||
|
||||
static char *__lookup_dev(char *path, dev_t dev, int dir_level, const int max_level)
|
||||
{
|
||||
struct dirent *entry;
|
||||
struct stat st;
|
||||
char *ptr;
|
||||
char *result = NULL;
|
||||
DIR *dir;
|
||||
int space;
|
||||
|
||||
/* Ignore strange nested directories */
|
||||
if (dir_level > max_level)
|
||||
return NULL;
|
||||
|
||||
path[PATH_MAX - 1] = '\0';
|
||||
ptr = path + strlen(path);
|
||||
*ptr++ = '/';
|
||||
*ptr = '\0';
|
||||
space = PATH_MAX - (ptr - path);
|
||||
|
||||
dir = opendir(path);
|
||||
if (!dir)
|
||||
return NULL;
|
||||
|
||||
while((entry = readdir(dir))) {
|
||||
if (entry->d_name[0] == '.' ||
|
||||
!strncmp(entry->d_name, "..", 2))
|
||||
continue;
|
||||
|
||||
if (dir_level == 0 &&
|
||||
(!strcmp(entry->d_name, "shm") ||
|
||||
!strcmp(entry->d_name, "fd") ||
|
||||
!strcmp(entry->d_name, "char") ||
|
||||
!strcmp(entry->d_name, "pts")))
|
||||
continue;
|
||||
|
||||
strncpy(ptr, entry->d_name, space);
|
||||
if (stat(path, &st) < 0)
|
||||
continue;
|
||||
|
||||
if (S_ISDIR(st.st_mode)) {
|
||||
result = __lookup_dev(path, dev, dir_level + 1, max_level);
|
||||
if (result)
|
||||
break;
|
||||
} else if (S_ISBLK(st.st_mode)) {
|
||||
/* workaround: ignore dm-X devices, these are internal kernel names */
|
||||
if (dir_level == 0 && dm_is_dm_kernel_name(entry->d_name))
|
||||
continue;
|
||||
if (st.st_rdev == dev) {
|
||||
result = strdup(path);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
closedir(dir);
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Non-udev systemd need to scan for device here.
|
||||
*/
|
||||
static char *lookup_dev_old(int major, int minor)
|
||||
{
|
||||
dev_t dev;
|
||||
char *result = NULL, buf[PATH_MAX + 1];
|
||||
|
||||
dev = makedev(major, minor);
|
||||
strncpy(buf, "/dev", PATH_MAX);
|
||||
buf[PATH_MAX] = '\0';
|
||||
|
||||
/* First try low level device */
|
||||
if ((result = __lookup_dev(buf, dev, 0, 0)))
|
||||
return result;
|
||||
|
||||
/* If it is dm, try DM dir */
|
||||
if (dm_is_dm_device(major, minor)) {
|
||||
strncpy(buf, dm_get_dir(), PATH_MAX);
|
||||
if ((result = __lookup_dev(buf, dev, 0, 0)))
|
||||
return result;
|
||||
}
|
||||
|
||||
strncpy(buf, "/dev", PATH_MAX);
|
||||
return __lookup_dev(buf, dev, 0, 4);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns string pointing to device in /dev according to "major:minor" dev_id
|
||||
*/
|
||||
char *crypt_lookup_dev(const char *dev_id)
|
||||
{
|
||||
int major, minor;
|
||||
char link[PATH_MAX], path[PATH_MAX], *devname, *devpath = NULL;
|
||||
struct stat st;
|
||||
ssize_t len;
|
||||
|
||||
if (sscanf(dev_id, "%d:%d", &major, &minor) != 2)
|
||||
return NULL;
|
||||
|
||||
if (snprintf(path, sizeof(path), "/sys/dev/block/%s", dev_id) < 0)
|
||||
return NULL;
|
||||
|
||||
len = readlink(path, link, sizeof(link));
|
||||
if (len < 0) {
|
||||
/* Without /sys use old scan */
|
||||
if (stat("/sys/dev/block", &st) < 0)
|
||||
return lookup_dev_old(major, minor);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
link[len] = '\0';
|
||||
devname = strrchr(link, '/');
|
||||
if (!devname)
|
||||
return NULL;
|
||||
devname++;
|
||||
|
||||
if (dm_is_dm_kernel_name(devname))
|
||||
devpath = dm_device_path("/dev/mapper/", major, minor);
|
||||
else if (snprintf(path, sizeof(path), "/dev/%s", devname) > 0)
|
||||
devpath = strdup(path);
|
||||
|
||||
/*
|
||||
* Check that path is correct.
|
||||
*/
|
||||
if (devpath && ((stat(devpath, &st) < 0) ||
|
||||
!S_ISBLK(st.st_mode) ||
|
||||
(st.st_rdev != makedev(major, minor)))) {
|
||||
free(devpath);
|
||||
/* Should never happen unless user mangles with dev nodes. */
|
||||
return lookup_dev_old(major, minor);
|
||||
}
|
||||
|
||||
return devpath;
|
||||
}
|
||||
|
||||
static int crypt_sysfs_get_major_minor(const char *kname, int *major, int *minor)
|
||||
{
|
||||
char path[PATH_MAX], tmp[64] = {0};
|
||||
int fd, r = 0;
|
||||
|
||||
if (snprintf(path, sizeof(path), "/sys/block/%s/dev", kname) < 0)
|
||||
return 0;
|
||||
|
||||
if ((fd = open(path, O_RDONLY)) < 0)
|
||||
return 0;
|
||||
r = read(fd, tmp, sizeof(tmp));
|
||||
close(fd);
|
||||
|
||||
if (r <= 0)
|
||||
return 0;
|
||||
|
||||
tmp[63] = '\0';
|
||||
if (sscanf(tmp, "%d:%d", major, minor) != 2)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int crypt_sysfs_get_holders_dir(const char *device, char *path, int size)
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
if (stat(device, &st) < 0 || !S_ISBLK(st.st_mode))
|
||||
return 0;
|
||||
|
||||
if (snprintf(path, size, "/sys/dev/block/%d:%d/holders",
|
||||
major(st.st_rdev), minor(st.st_rdev)) < 0)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int crypt_sysfs_check_crypt_segment(const char *device, uint64_t offset, uint64_t size)
|
||||
{
|
||||
DIR *dir;
|
||||
struct dirent *d;
|
||||
char path[PATH_MAX], *dmname;
|
||||
int major, minor, r = 0;
|
||||
|
||||
if (!crypt_sysfs_get_holders_dir(device, path, sizeof(path)))
|
||||
return -EINVAL;
|
||||
|
||||
if (!(dir = opendir(path)))
|
||||
return -EINVAL;
|
||||
|
||||
while (!r && (d = readdir(dir))) {
|
||||
if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, ".."))
|
||||
continue;
|
||||
|
||||
if (!dm_is_dm_kernel_name(d->d_name)) {
|
||||
r = -EBUSY;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!crypt_sysfs_get_major_minor(d->d_name, &major, &minor)) {
|
||||
r = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(dmname = dm_device_path(NULL, major, minor))) {
|
||||
r = -EINVAL;
|
||||
break;
|
||||
}
|
||||
r = dm_check_segment(dmname, offset, size);
|
||||
free(dmname);
|
||||
}
|
||||
closedir(dir);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int crypt_sysfs_get_rotational(int major, int minor, int *rotational)
|
||||
{
|
||||
char path[PATH_MAX], tmp[64] = {0};
|
||||
int fd, r;
|
||||
|
||||
if (snprintf(path, sizeof(path), "/sys/dev/block/%d:%d/queue/rotational",
|
||||
major, minor) < 0)
|
||||
return 0;
|
||||
|
||||
if ((fd = open(path, O_RDONLY)) < 0)
|
||||
return 0;
|
||||
r = read(fd, tmp, sizeof(tmp));
|
||||
close(fd);
|
||||
|
||||
if (r <= 0)
|
||||
return 0;
|
||||
|
||||
if (sscanf(tmp, "%d", rotational) != 1)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
103
lib/utils_dm.h
Normal file
103
lib/utils_dm.h
Normal file
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* libdevmapper - device-mapper backend for cryptsetup
|
||||
*
|
||||
* Copyright (C) 2004, Christophe Saout <christophe@saout.de>
|
||||
* Copyright (C) 2004-2007, Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2009-2012, 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
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _UTILS_DM_H
|
||||
#define _UTILS_DM_H
|
||||
|
||||
/* device-mapper library helpers */
|
||||
#include <inttypes.h>
|
||||
|
||||
struct crypt_device;
|
||||
struct volume_key;
|
||||
struct crypt_params_verity;
|
||||
|
||||
/* Device mapper backend - kernel support flags */
|
||||
#define DM_KEY_WIPE_SUPPORTED (1 << 0) /* key wipe message */
|
||||
#define DM_LMK_SUPPORTED (1 << 1) /* lmk mode */
|
||||
#define DM_SECURE_SUPPORTED (1 << 2) /* wipe (secure) buffer flag */
|
||||
#define DM_PLAIN64_SUPPORTED (1 << 3) /* plain64 IV */
|
||||
#define DM_DISCARDS_SUPPORTED (1 << 4) /* discards/TRIM option is supported */
|
||||
#define DM_VERITY_SUPPORTED (1 << 5) /* dm-verity target supported */
|
||||
uint32_t dm_flags(void);
|
||||
|
||||
#define DM_ACTIVE_DEVICE (1 << 0)
|
||||
#define DM_ACTIVE_UUID (1 << 1)
|
||||
|
||||
#define DM_ACTIVE_CRYPT_CIPHER (1 << 2)
|
||||
#define DM_ACTIVE_CRYPT_KEYSIZE (1 << 3)
|
||||
#define DM_ACTIVE_CRYPT_KEY (1 << 4)
|
||||
|
||||
#define DM_ACTIVE_VERITY_ROOT_HASH (1 << 5)
|
||||
#define DM_ACTIVE_VERITY_HASH_DEVICE (1 << 6)
|
||||
#define DM_ACTIVE_VERITY_PARAMS (1 << 7)
|
||||
|
||||
struct crypt_dm_active_device {
|
||||
enum { DM_CRYPT = 0, DM_VERITY } target;
|
||||
uint64_t size; /* active device size */
|
||||
uint32_t flags; /* activation flags */
|
||||
const char *uuid;
|
||||
const char *data_device;
|
||||
union {
|
||||
struct {
|
||||
const char *cipher;
|
||||
|
||||
/* Active key for device */
|
||||
struct volume_key *vk;
|
||||
|
||||
/* struct crypt_active_device */
|
||||
uint64_t offset; /* offset in sectors */
|
||||
uint64_t iv_offset; /* IV initilisation sector */
|
||||
} crypt;
|
||||
struct {
|
||||
const char *hash_device;
|
||||
|
||||
const char *root_hash;
|
||||
uint32_t root_hash_size;
|
||||
|
||||
uint64_t hash_offset; /* hash offset in blocks (not header) */
|
||||
struct crypt_params_verity *vp;
|
||||
} verity;
|
||||
} u;
|
||||
};
|
||||
|
||||
const char *dm_get_dir(void);
|
||||
int dm_init(struct crypt_device *context, int check_kernel);
|
||||
void dm_exit(void);
|
||||
int dm_remove_device(const char *name, int force, uint64_t size);
|
||||
int dm_status_device(const char *name);
|
||||
int dm_status_suspended(const char *name);
|
||||
int dm_status_verity_ok(const char *name);
|
||||
int dm_query_device(const char *name, uint32_t get_flags,
|
||||
struct crypt_dm_active_device *dmd);
|
||||
int dm_create_device(const char *name,
|
||||
const char *type,
|
||||
struct crypt_dm_active_device *dmd,
|
||||
int reload);
|
||||
int dm_suspend_and_wipe_key(const char *name);
|
||||
int dm_resume_and_reinstate_key(const char *name,
|
||||
size_t key_size,
|
||||
const char *key);
|
||||
char *dm_device_path(const char *prefix, int major, int minor);
|
||||
int dm_is_dm_device(int major, int minor);
|
||||
int dm_is_dm_kernel_name(const char *name);
|
||||
int dm_check_segment(const char *name, uint64_t offset, uint64_t size);
|
||||
|
||||
#endif /* _UTILS_DM_H */
|
||||
62
lib/utils_fips.c
Normal file
62
lib/utils_fips.c
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* FIPS mode utilities
|
||||
*
|
||||
* Copyright (C) 2011-2012, 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
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include "libcryptsetup.h"
|
||||
#include "nls.h"
|
||||
#include "utils_fips.h"
|
||||
#include "config.h"
|
||||
|
||||
#if !ENABLE_FIPS
|
||||
int crypt_fips_mode(void) { return 0; }
|
||||
void crypt_fips_libcryptsetup_check(struct crypt_device *cd) {}
|
||||
void crypt_fips_self_check(struct crypt_device *cd) {}
|
||||
#else
|
||||
#include <fipscheck.h>
|
||||
|
||||
int crypt_fips_mode(void)
|
||||
{
|
||||
return FIPSCHECK_kernel_fips_mode();
|
||||
}
|
||||
|
||||
static void crypt_fips_verify(struct crypt_device *cd,
|
||||
const char *name, const char *function)
|
||||
{
|
||||
if (!crypt_fips_mode())
|
||||
return;
|
||||
|
||||
if (!FIPSCHECK_verify(name, function)) {
|
||||
crypt_log(cd, CRYPT_LOG_ERROR, _("FIPS checksum verification failed.\n"));
|
||||
_exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
crypt_log(cd, CRYPT_LOG_VERBOSE, _("Running in FIPS mode.\n"));
|
||||
}
|
||||
|
||||
void crypt_fips_libcryptsetup_check(struct crypt_device *cd)
|
||||
{
|
||||
crypt_fips_verify(cd, LIBCRYPTSETUP_VERSION_FIPS, "crypt_init");
|
||||
}
|
||||
|
||||
void crypt_fips_self_check(struct crypt_device *cd)
|
||||
{
|
||||
crypt_fips_verify(cd, NULL, NULL);
|
||||
}
|
||||
#endif /* ENABLE_FIPS */
|
||||
29
lib/utils_fips.h
Normal file
29
lib/utils_fips.h
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* FIPS mode utilities
|
||||
*
|
||||
* Copyright (C) 2011-2012, 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
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _UTILS_FIPS_H
|
||||
#define _UTILS_FIPS_H
|
||||
|
||||
struct crypt_device;
|
||||
|
||||
int crypt_fips_mode(void);
|
||||
void crypt_fips_libcryptsetup_check(struct crypt_device *cd);
|
||||
void crypt_fips_self_check(struct crypt_device *cd);
|
||||
|
||||
#endif /* _UTILS_FIPS_H */
|
||||
226
lib/utils_loop.c
Normal file
226
lib/utils_loop.c
Normal file
@@ -0,0 +1,226 @@
|
||||
/*
|
||||
* loopback block device utilities
|
||||
*
|
||||
* Copyright (C) 2011-2012, 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
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <linux/loop.h>
|
||||
|
||||
#include "utils_loop.h"
|
||||
|
||||
#define LOOP_DEV_MAJOR 7
|
||||
|
||||
#ifndef LO_FLAGS_AUTOCLEAR
|
||||
#define LO_FLAGS_AUTOCLEAR 4
|
||||
#endif
|
||||
|
||||
#ifndef LOOP_CTL_GET_FREE
|
||||
#define LOOP_CTL_GET_FREE 0x4C82
|
||||
#endif
|
||||
|
||||
static char *crypt_loop_get_device_old(void)
|
||||
{
|
||||
char dev[20];
|
||||
int i, loop_fd;
|
||||
struct stat st;
|
||||
struct loop_info64 lo64 = {0};
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
sprintf(dev, "/dev/loop%d", i);
|
||||
if (stat(dev, &st) || !S_ISBLK(st.st_mode))
|
||||
return NULL;
|
||||
|
||||
loop_fd = open(dev, O_RDONLY);
|
||||
if (loop_fd < 0)
|
||||
return NULL;
|
||||
|
||||
if (ioctl(loop_fd, LOOP_GET_STATUS64, &lo64) &&
|
||||
errno == ENXIO) {
|
||||
close(loop_fd);
|
||||
return strdup(dev);
|
||||
}
|
||||
close(loop_fd);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *crypt_loop_get_device(void)
|
||||
{
|
||||
char dev[64];
|
||||
int i, loop_fd;
|
||||
struct stat st;
|
||||
|
||||
loop_fd = open("/dev/loop-control", O_RDONLY);
|
||||
if (loop_fd < 0)
|
||||
return crypt_loop_get_device_old();
|
||||
|
||||
i = ioctl(loop_fd, LOOP_CTL_GET_FREE);
|
||||
if (i < 0) {
|
||||
close(loop_fd);
|
||||
return NULL;
|
||||
}
|
||||
close(loop_fd);
|
||||
|
||||
if (sprintf(dev, "/dev/loop%d", i) < 0)
|
||||
return NULL;
|
||||
|
||||
if (stat(dev, &st) || !S_ISBLK(st.st_mode))
|
||||
return NULL;
|
||||
|
||||
return strdup(dev);
|
||||
}
|
||||
|
||||
int crypt_loop_attach(const char *loop, const char *file, int offset,
|
||||
int autoclear, int *readonly)
|
||||
{
|
||||
struct loop_info64 lo64 = {0};
|
||||
int loop_fd = -1, file_fd = -1, r = 1;
|
||||
|
||||
file_fd = open(file, (*readonly ? O_RDONLY : O_RDWR) | O_EXCL);
|
||||
if (file_fd < 0 && (errno == EROFS || errno == EACCES) && !*readonly) {
|
||||
*readonly = 1;
|
||||
file_fd = open(file, O_RDONLY | O_EXCL);
|
||||
}
|
||||
if (file_fd < 0)
|
||||
goto out;
|
||||
|
||||
loop_fd = open(loop, *readonly ? O_RDONLY : O_RDWR);
|
||||
if (loop_fd < 0)
|
||||
goto out;
|
||||
|
||||
strncpy((char*)lo64.lo_file_name, file, LO_NAME_SIZE);
|
||||
lo64.lo_offset = offset;
|
||||
if (autoclear)
|
||||
lo64.lo_flags |= LO_FLAGS_AUTOCLEAR;
|
||||
|
||||
if (ioctl(loop_fd, LOOP_SET_FD, file_fd) < 0)
|
||||
goto out;
|
||||
|
||||
if (ioctl(loop_fd, LOOP_SET_STATUS64, &lo64) < 0) {
|
||||
(void)ioctl(loop_fd, LOOP_CLR_FD, 0);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Verify that autoclear is really set */
|
||||
if (autoclear) {
|
||||
memset(&lo64, 0, sizeof(lo64));
|
||||
if (ioctl(loop_fd, LOOP_GET_STATUS64, &lo64) < 0 ||
|
||||
!(lo64.lo_flags & LO_FLAGS_AUTOCLEAR)) {
|
||||
(void)ioctl(loop_fd, LOOP_CLR_FD, 0);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
r = 0;
|
||||
out:
|
||||
if (r && loop_fd >= 0)
|
||||
close(loop_fd);
|
||||
if (file_fd >= 0)
|
||||
close(file_fd);
|
||||
return r ? -1 : loop_fd;
|
||||
}
|
||||
|
||||
int crypt_loop_detach(const char *loop)
|
||||
{
|
||||
int loop_fd = -1, r = 1;
|
||||
|
||||
loop_fd = open(loop, O_RDONLY);
|
||||
if (loop_fd < 0)
|
||||
return 1;
|
||||
|
||||
if (!ioctl(loop_fd, LOOP_CLR_FD, 0))
|
||||
r = 0;
|
||||
|
||||
close(loop_fd);
|
||||
return r;
|
||||
}
|
||||
|
||||
static char *_ioctl_backing_file(const char *loop)
|
||||
{
|
||||
struct loop_info64 lo64 = {0};
|
||||
int loop_fd;
|
||||
|
||||
loop_fd = open(loop, O_RDONLY);
|
||||
if (loop_fd < 0)
|
||||
return NULL;
|
||||
|
||||
if (ioctl(loop_fd, LOOP_GET_STATUS64, &lo64) < 0) {
|
||||
close(loop_fd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lo64.lo_file_name[LO_NAME_SIZE-2] = '*';
|
||||
lo64.lo_file_name[LO_NAME_SIZE-1] = 0;
|
||||
|
||||
close(loop_fd);
|
||||
|
||||
return strdup((char*)lo64.lo_file_name);
|
||||
}
|
||||
|
||||
static char *_sysfs_backing_file(const char *loop)
|
||||
{
|
||||
struct stat st;
|
||||
char buf[PATH_MAX];
|
||||
size_t len;
|
||||
int fd;
|
||||
|
||||
if (stat(loop, &st) || !S_ISBLK(st.st_mode))
|
||||
return NULL;
|
||||
|
||||
snprintf(buf, sizeof(buf), "/sys/dev/block/%d:%d/loop/backing_file",
|
||||
major(st.st_rdev), minor(st.st_rdev));
|
||||
|
||||
fd = open(buf, O_RDONLY);
|
||||
if (fd < 0)
|
||||
return NULL;
|
||||
|
||||
len = read(fd, buf, PATH_MAX);
|
||||
close(fd);
|
||||
if (len < 2)
|
||||
return NULL;
|
||||
|
||||
buf[len - 1] = '\0';
|
||||
return strdup(buf);
|
||||
}
|
||||
|
||||
char *crypt_loop_backing_file(const char *loop)
|
||||
{
|
||||
char *bf = _sysfs_backing_file(loop);
|
||||
return bf ?: _ioctl_backing_file(loop);
|
||||
}
|
||||
|
||||
int crypt_loop_device(const char *loop)
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
if (!loop)
|
||||
return 0;
|
||||
|
||||
if (stat(loop, &st) || !S_ISBLK(st.st_mode) ||
|
||||
major(st.st_rdev) != LOOP_DEV_MAJOR)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
32
lib/utils_loop.h
Normal file
32
lib/utils_loop.h
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* loopback block device utilities
|
||||
*
|
||||
* Copyright (C) 2011-2012, 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
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _UTILS_LOOP_H
|
||||
#define _UTILS_LOOP_H
|
||||
|
||||
/* loopback device helpers */
|
||||
|
||||
char *crypt_loop_get_device(void);
|
||||
char *crypt_loop_backing_file(const char *loop);
|
||||
int crypt_loop_device(const char *loop);
|
||||
int crypt_loop_attach(const char *loop, const char *file, int offset,
|
||||
int autoclear, int *readonly);
|
||||
int crypt_loop_detach(const char *loop);
|
||||
|
||||
#endif /* _UTILS_LOOP_H */
|
||||
187
lib/utils_wipe.c
Normal file
187
lib/utils_wipe.c
Normal file
@@ -0,0 +1,187 @@
|
||||
/*
|
||||
* utils_wipe - wipe a device
|
||||
*
|
||||
* Copyright (C) 2004-2007, Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2011-2012, 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
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "libcryptsetup.h"
|
||||
#include "internal.h"
|
||||
|
||||
#define MAXIMUM_WIPE_BYTES 1024 * 1024 * 32 /* 32 MiB */
|
||||
|
||||
static ssize_t _crypt_wipe_zero(int fd, char *buffer, uint64_t offset, uint64_t size)
|
||||
{
|
||||
memset(buffer, 0, size);
|
||||
return write_lseek_blockwise(fd, buffer, size, offset);
|
||||
}
|
||||
|
||||
static ssize_t _crypt_wipe_random(int fd, char *buffer, uint64_t offset, uint64_t size)
|
||||
{
|
||||
if (crypt_random_get(NULL, buffer, size, CRYPT_RND_NORMAL) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
return write_lseek_blockwise(fd, buffer, size, offset);
|
||||
}
|
||||
|
||||
/*
|
||||
* Wipe using Peter Gutmann method described in
|
||||
* http://www.cs.auckland.ac.nz/~pgut001/pubs/secure_del.html
|
||||
*/
|
||||
static void wipeSpecial(char *buffer, size_t buffer_size, unsigned int turn)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
unsigned char write_modes[][3] = {
|
||||
{"\x55\x55\x55"}, {"\xaa\xaa\xaa"}, {"\x92\x49\x24"},
|
||||
{"\x49\x24\x92"}, {"\x24\x92\x49"}, {"\x00\x00\x00"},
|
||||
{"\x11\x11\x11"}, {"\x22\x22\x22"}, {"\x33\x33\x33"},
|
||||
{"\x44\x44\x44"}, {"\x55\x55\x55"}, {"\x66\x66\x66"},
|
||||
{"\x77\x77\x77"}, {"\x88\x88\x88"}, {"\x99\x99\x99"},
|
||||
{"\xaa\xaa\xaa"}, {"\xbb\xbb\xbb"}, {"\xcc\xcc\xcc"},
|
||||
{"\xdd\xdd\xdd"}, {"\xee\xee\xee"}, {"\xff\xff\xff"},
|
||||
{"\x92\x49\x24"}, {"\x49\x24\x92"}, {"\x24\x92\x49"},
|
||||
{"\x6d\xb6\xdb"}, {"\xb6\xdb\x6d"}, {"\xdb\x6d\xb6"}
|
||||
};
|
||||
|
||||
for(i = 0; i < buffer_size / 3; ++i) {
|
||||
memcpy(buffer, write_modes[turn], 3);
|
||||
buffer += 3;
|
||||
}
|
||||
}
|
||||
|
||||
static ssize_t _crypt_wipe_disk(int fd, char *buffer, uint64_t offset, uint64_t size)
|
||||
{
|
||||
int r;
|
||||
unsigned int i;
|
||||
ssize_t written;
|
||||
|
||||
for(i = 0; i < 39; ++i) {
|
||||
if (i < 5) {
|
||||
r = crypt_random_get(NULL, buffer, size, CRYPT_RND_NORMAL);
|
||||
} else if(i >= 5 && i < 32) {
|
||||
wipeSpecial(buffer, size, i - 5);
|
||||
r = 0;
|
||||
} else if(i >= 32 && i < 38) {
|
||||
r = crypt_random_get(NULL, buffer, size, CRYPT_RND_NORMAL);
|
||||
} else if(i >= 38 && i < 39) {
|
||||
memset(buffer, 0xFF, size);
|
||||
r = 0;
|
||||
}
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
written = write_lseek_blockwise(fd, buffer, size, offset);
|
||||
if (written < 0 || written != (ssize_t)size)
|
||||
return written;
|
||||
}
|
||||
|
||||
/* Rewrite it finally with random */
|
||||
return _crypt_wipe_random(fd, buffer, offset, size);
|
||||
}
|
||||
|
||||
static ssize_t _crypt_wipe_ssd(int fd, char *buffer, uint64_t offset, uint64_t size)
|
||||
{
|
||||
// FIXME: for now just rewrite it by random
|
||||
return _crypt_wipe_random(fd, buffer, offset, size);
|
||||
}
|
||||
|
||||
int crypt_wipe(const char *device,
|
||||
uint64_t offset,
|
||||
uint64_t size,
|
||||
crypt_wipe_type type,
|
||||
int exclusive)
|
||||
{
|
||||
struct stat st;
|
||||
char *buffer;
|
||||
int devfd, flags, rotational;
|
||||
ssize_t written;
|
||||
|
||||
if (!size || size % SECTOR_SIZE || (size > MAXIMUM_WIPE_BYTES)) {
|
||||
log_dbg("Unsuported wipe size for device %s: %ld.",
|
||||
device, (unsigned long)size);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (stat(device, &st) < 0) {
|
||||
log_dbg("Device %s not found.", device);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (type == CRYPT_WIPE_DISK) {
|
||||
if (!crypt_sysfs_get_rotational(major(st.st_rdev),
|
||||
minor(st.st_rdev),
|
||||
&rotational))
|
||||
rotational = 1;
|
||||
log_dbg("Rotational flag is %d.", rotational);
|
||||
if (!rotational)
|
||||
type = CRYPT_WIPE_SSD;
|
||||
}
|
||||
|
||||
buffer = malloc(size);
|
||||
if (!buffer)
|
||||
return -ENOMEM;
|
||||
|
||||
flags = O_RDWR | O_DIRECT | O_SYNC;
|
||||
|
||||
/* use O_EXCL only for block devices */
|
||||
if (exclusive && S_ISBLK(st.st_mode))
|
||||
flags |= O_EXCL;
|
||||
|
||||
devfd = open(device, flags);
|
||||
if (devfd == -1) {
|
||||
free(buffer);
|
||||
return errno == EBUSY ? -EBUSY : -EINVAL;
|
||||
}
|
||||
|
||||
// FIXME: use fixed block size and loop here
|
||||
switch (type) {
|
||||
case CRYPT_WIPE_ZERO:
|
||||
written = _crypt_wipe_zero(devfd, buffer, offset, size);
|
||||
break;
|
||||
case CRYPT_WIPE_DISK:
|
||||
written = _crypt_wipe_disk(devfd, buffer, offset, size);
|
||||
break;
|
||||
case CRYPT_WIPE_SSD:
|
||||
written = _crypt_wipe_ssd(devfd, buffer, offset, size);
|
||||
break;
|
||||
case CRYPT_WIPE_RANDOM:
|
||||
written = _crypt_wipe_random(devfd, buffer, offset, size);
|
||||
break;
|
||||
default:
|
||||
log_dbg("Unsuported wipe type requested: (%d)", type);
|
||||
written = -1;
|
||||
}
|
||||
|
||||
close(devfd);
|
||||
free(buffer);
|
||||
|
||||
if (written != (ssize_t)size || written < 0)
|
||||
return -EIO;
|
||||
|
||||
return 0;
|
||||
}
|
||||
16
lib/verity/Makefile.am
Normal file
16
lib/verity/Makefile.am
Normal file
@@ -0,0 +1,16 @@
|
||||
moduledir = $(libdir)/cryptsetup
|
||||
|
||||
noinst_LTLIBRARIES = libverity.la
|
||||
|
||||
libverity_la_CFLAGS = -Wall @CRYPTO_CFLAGS@
|
||||
|
||||
libverity_la_SOURCES = \
|
||||
verity_hash.c \
|
||||
verity.c \
|
||||
verity.h
|
||||
|
||||
INCLUDES = -D_GNU_SOURCE \
|
||||
-D_LARGEFILE64_SOURCE \
|
||||
-D_FILE_OFFSET_BITS=64 \
|
||||
-I$(top_srcdir)/lib \
|
||||
-I$(top_srcdir)/lib/crypto_backend
|
||||
279
lib/verity/verity.c
Normal file
279
lib/verity/verity.c
Normal file
@@ -0,0 +1,279 @@
|
||||
/*
|
||||
* dm-verity volume handling
|
||||
*
|
||||
* Copyright (C) 2012, 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
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <netinet/in.h>
|
||||
#include <uuid/uuid.h>
|
||||
|
||||
#include "libcryptsetup.h"
|
||||
#include "verity.h"
|
||||
#include "internal.h"
|
||||
|
||||
#define VERITY_SIGNATURE "verity\0\0"
|
||||
|
||||
/* http://code.google.com/p/cryptsetup/wiki/DMVerity#Verity_superblock_format */
|
||||
struct verity_sb {
|
||||
uint8_t signature[8]; /* "verity\0\0" */
|
||||
uint32_t version; /* superblock version */
|
||||
uint32_t hash_type; /* 0 - Chrome OS, 1 - normal */
|
||||
uint8_t uuid[16]; /* UUID of hash device */
|
||||
uint8_t algorithm[32];/* hash algorithm name */
|
||||
uint32_t data_block_size; /* data block in bytes */
|
||||
uint32_t hash_block_size; /* hash block in bytes */
|
||||
uint64_t data_blocks; /* number of data blocks */
|
||||
uint16_t salt_size; /* salt size */
|
||||
uint8_t _pad1[6];
|
||||
uint8_t salt[256]; /* salt */
|
||||
uint8_t _pad2[168];
|
||||
} __attribute__((packed));
|
||||
|
||||
/* Read verity superblock from disk */
|
||||
int VERITY_read_sb(struct crypt_device *cd,
|
||||
const char *device,
|
||||
uint64_t sb_offset,
|
||||
char **uuid_string,
|
||||
struct crypt_params_verity *params)
|
||||
{
|
||||
struct verity_sb sb = {};
|
||||
ssize_t hdr_size = sizeof(struct verity_sb);
|
||||
int devfd = 0, sb_version;
|
||||
|
||||
log_dbg("Reading VERITY header of size %u on device %s, offset %" PRIu64 ".",
|
||||
sizeof(struct verity_sb), device, sb_offset);
|
||||
|
||||
if (params->flags & CRYPT_VERITY_NO_HEADER) {
|
||||
log_err(cd, _("Verity device doesn't use on-disk header.\n"), device);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (sb_offset % 512) {
|
||||
log_err(cd, _("Unsupported VERITY hash offset.\n"));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
devfd = open(device ,O_RDONLY | O_DIRECT);
|
||||
if(devfd == -1) {
|
||||
log_err(cd, _("Cannot open device %s.\n"), device);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if(lseek(devfd, sb_offset, SEEK_SET) < 0 ||
|
||||
read_blockwise(devfd, &sb, hdr_size) < hdr_size) {
|
||||
close(devfd);
|
||||
return -EIO;
|
||||
}
|
||||
close(devfd);
|
||||
|
||||
if (memcmp(sb.signature, VERITY_SIGNATURE, sizeof(sb.signature))) {
|
||||
log_err(cd, _("Device %s is not a valid VERITY device.\n"), device);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
sb_version = le32_to_cpu(sb.version);
|
||||
if (sb_version != 1) {
|
||||
log_err(cd, _("Unsupported VERITY version %d.\n"), sb_version);
|
||||
return -EINVAL;
|
||||
}
|
||||
params->hash_type = le32_to_cpu(sb.hash_type);
|
||||
if (params->hash_type > VERITY_MAX_HASH_TYPE) {
|
||||
log_err(cd, _("Unsupported VERITY hash type %d.\n"), params->hash_type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
params->data_block_size = le32_to_cpu(sb.data_block_size);
|
||||
params->hash_block_size = le32_to_cpu(sb.hash_block_size);
|
||||
if (VERITY_BLOCK_SIZE_OK(params->data_block_size) ||
|
||||
VERITY_BLOCK_SIZE_OK(params->hash_block_size)) {
|
||||
log_err(cd, _("Unsupported VERITY block size.\n"));
|
||||
return -EINVAL;
|
||||
}
|
||||
params->data_size = le64_to_cpu(sb.data_blocks);
|
||||
|
||||
params->hash_name = strndup((const char*)sb.algorithm, sizeof(sb.algorithm));
|
||||
if (!params->hash_name)
|
||||
return -ENOMEM;
|
||||
if (crypt_hash_size(params->hash_name) <= 0) {
|
||||
log_err(cd, _("Hash algorithm %s not supported.\n"),
|
||||
params->hash_name);
|
||||
free(CONST_CAST(char*)params->hash_name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
params->salt_size = le16_to_cpu(sb.salt_size);
|
||||
if (params->salt_size > sizeof(sb.salt)) {
|
||||
log_err(cd, _("VERITY header corrupted.\n"));
|
||||
free(CONST_CAST(char*)params->hash_name);
|
||||
return -EINVAL;
|
||||
}
|
||||
params->salt = malloc(params->salt_size);
|
||||
if (!params->salt) {
|
||||
free(CONST_CAST(char*)params->hash_name);
|
||||
return -ENOMEM;
|
||||
}
|
||||
memcpy(CONST_CAST(char*)params->salt, sb.salt, params->salt_size);
|
||||
|
||||
if ((*uuid_string = malloc(40)))
|
||||
uuid_unparse(sb.uuid, *uuid_string);
|
||||
|
||||
params->hash_area_offset = sb_offset;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Write verity superblock to disk */
|
||||
int VERITY_write_sb(struct crypt_device *cd,
|
||||
const char *device,
|
||||
uint64_t sb_offset,
|
||||
const char *uuid_string,
|
||||
struct crypt_params_verity *params)
|
||||
{
|
||||
struct verity_sb sb = {};
|
||||
ssize_t hdr_size = sizeof(struct verity_sb);
|
||||
uuid_t uuid;
|
||||
int r, devfd = 0;
|
||||
|
||||
log_dbg("Updating VERITY header of size %u on device %s, offset %" PRIu64 ".",
|
||||
sizeof(struct verity_sb), device, sb_offset);
|
||||
|
||||
if (!uuid_string || uuid_parse(uuid_string, uuid) == -1) {
|
||||
log_err(cd, _("Wrong VERITY UUID format provided.\n"), device);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (params->flags & CRYPT_VERITY_NO_HEADER) {
|
||||
log_err(cd, _("Verity device doesn't use on-disk header.\n"), device);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
devfd = open(device, O_RDWR | O_DIRECT);
|
||||
if(devfd == -1) {
|
||||
log_err(cd, _("Cannot open device %s.\n"), device);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
memcpy(&sb.signature, VERITY_SIGNATURE, sizeof(sb.signature));
|
||||
sb.version = cpu_to_le32(1);
|
||||
sb.hash_type = cpu_to_le32(params->hash_type);
|
||||
sb.data_block_size = cpu_to_le32(params->data_block_size);
|
||||
sb.hash_block_size = cpu_to_le32(params->hash_block_size);
|
||||
sb.salt_size = cpu_to_le16(params->salt_size);
|
||||
sb.data_blocks = cpu_to_le64(params->data_size);
|
||||
strncpy((char *)sb.algorithm, params->hash_name, sizeof(sb.algorithm));
|
||||
memcpy(sb.salt, params->salt, params->salt_size);
|
||||
memcpy(sb.uuid, uuid, sizeof(sb.uuid));
|
||||
|
||||
r = write_lseek_blockwise(devfd, (char*)&sb, hdr_size, sb_offset) < hdr_size ? -EIO : 0;
|
||||
if (r)
|
||||
log_err(cd, _("Error during update of verity header on device %s.\n"), device);
|
||||
close(devfd);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Calculate hash offset in hash blocks */
|
||||
uint64_t VERITY_hash_offset_block(struct crypt_params_verity *params)
|
||||
{
|
||||
uint64_t hash_offset = params->hash_area_offset;
|
||||
|
||||
if (params->flags & CRYPT_VERITY_NO_HEADER)
|
||||
return hash_offset / params->hash_block_size;
|
||||
|
||||
hash_offset += sizeof(struct verity_sb);
|
||||
hash_offset += params->hash_block_size - 1;
|
||||
|
||||
return hash_offset / params->hash_block_size;
|
||||
}
|
||||
|
||||
int VERITY_UUID_generate(struct crypt_device *cd, char **uuid_string)
|
||||
{
|
||||
uuid_t uuid;
|
||||
|
||||
if (!(*uuid_string = malloc(40)))
|
||||
return -ENOMEM;
|
||||
uuid_generate(uuid);
|
||||
uuid_unparse(uuid, *uuid_string);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Activate verity device in kernel device-mapper */
|
||||
int VERITY_activate(struct crypt_device *cd,
|
||||
const char *name,
|
||||
const char *hash_device,
|
||||
const char *root_hash,
|
||||
size_t root_hash_size,
|
||||
struct crypt_params_verity *verity_hdr,
|
||||
uint32_t activation_flags)
|
||||
{
|
||||
struct crypt_dm_active_device dmd;
|
||||
uint64_t offset = 0;
|
||||
int r;
|
||||
|
||||
log_dbg("Trying to activate VERITY device %s using hash %s.",
|
||||
name ?: "[none]", verity_hdr->hash_name);
|
||||
|
||||
if (verity_hdr->flags & CRYPT_VERITY_CHECK_HASH) {
|
||||
log_dbg("Verification of data in userspace required.");
|
||||
r = VERITY_verify(cd, verity_hdr,
|
||||
crypt_get_device_name(cd), hash_device,
|
||||
root_hash, root_hash_size);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
if (!name)
|
||||
return 0;
|
||||
|
||||
dmd.target = DM_VERITY;
|
||||
dmd.data_device = crypt_get_device_name(cd);
|
||||
dmd.u.verity.hash_device = hash_device;
|
||||
dmd.u.verity.root_hash = root_hash;
|
||||
dmd.u.verity.root_hash_size = root_hash_size;
|
||||
dmd.u.verity.hash_offset = VERITY_hash_offset_block(verity_hdr),
|
||||
dmd.flags = activation_flags;
|
||||
dmd.size = verity_hdr->data_size * verity_hdr->data_block_size / 512;
|
||||
dmd.uuid = crypt_get_uuid(cd);
|
||||
dmd.u.verity.vp = verity_hdr;
|
||||
|
||||
r = device_check_and_adjust(cd, dmd.data_device, DEV_EXCL,
|
||||
&dmd.size, &offset, &dmd.flags);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = dm_create_device(name, CRYPT_VERITY, &dmd, 0);
|
||||
if (!r && !(dm_flags() & DM_VERITY_SUPPORTED)) {
|
||||
log_err(cd, _("Kernel doesn't support dm-verity mapping.\n"));
|
||||
return -ENOTSUP;
|
||||
}
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = dm_status_verity_ok(name);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!r)
|
||||
log_err(cd, _("Verity device detected corruption after activation.\n"));
|
||||
return 0;
|
||||
}
|
||||
71
lib/verity/verity.h
Normal file
71
lib/verity/verity.h
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* dm-verity volume handling
|
||||
*
|
||||
* Copyright (C) 2012, 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
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _VERITY_H
|
||||
#define _VERITY_H
|
||||
|
||||
#include <unistd.h>
|
||||
#include "config.h"
|
||||
|
||||
#define VERITY_MAX_HASH_TYPE 1
|
||||
#define VERITY_BLOCK_SIZE_OK(x) ((x) % 512 || (x) < 512 || \
|
||||
(x) > (512 * 1024) || (x) & ((x)-1))
|
||||
|
||||
struct crypt_device;
|
||||
struct crypt_params_verity;
|
||||
|
||||
int VERITY_read_sb(struct crypt_device *cd,
|
||||
const char *device,
|
||||
uint64_t sb_offset,
|
||||
char **uuid,
|
||||
struct crypt_params_verity *params);
|
||||
|
||||
int VERITY_write_sb(struct crypt_device *cd,
|
||||
const char *device,
|
||||
uint64_t sb_offset,
|
||||
const char *uuid_string,
|
||||
struct crypt_params_verity *params);
|
||||
|
||||
int VERITY_activate(struct crypt_device *cd,
|
||||
const char *name,
|
||||
const char *hash_device,
|
||||
const char *root_hash,
|
||||
size_t root_hash_size,
|
||||
struct crypt_params_verity *verity_hdr,
|
||||
uint32_t activation_flags);
|
||||
|
||||
int VERITY_verify(struct crypt_device *cd,
|
||||
struct crypt_params_verity *verity_hdr,
|
||||
const char *data_device,
|
||||
const char *hash_device,
|
||||
const char *root_hash,
|
||||
size_t root_hash_size);
|
||||
|
||||
int VERITY_create(struct crypt_device *cd,
|
||||
struct crypt_params_verity *verity_hdr,
|
||||
const char *data_device,
|
||||
const char *hash_device,
|
||||
char *root_hash,
|
||||
size_t root_hash_size);
|
||||
|
||||
uint64_t VERITY_hash_offset_block(struct crypt_params_verity *params);
|
||||
|
||||
int VERITY_UUID_generate(struct crypt_device *cd, char **uuid_string);
|
||||
|
||||
#endif
|
||||
431
lib/verity/verity_hash.c
Normal file
431
lib/verity/verity_hash.c
Normal file
@@ -0,0 +1,431 @@
|
||||
/*
|
||||
* dm-verity volume handling
|
||||
*
|
||||
* Copyright (C) 2012, 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
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "verity.h"
|
||||
#include "internal.h"
|
||||
|
||||
#define VERITY_MAX_LEVELS 63
|
||||
|
||||
static unsigned get_bits_up(size_t u)
|
||||
{
|
||||
unsigned i = 0;
|
||||
while ((1U << i) < u)
|
||||
i++;
|
||||
return i;
|
||||
}
|
||||
|
||||
static unsigned get_bits_down(size_t u)
|
||||
{
|
||||
unsigned i = 0;
|
||||
while ((u >> i) > 1U)
|
||||
i++;
|
||||
return i;
|
||||
}
|
||||
|
||||
static int verify_zero(struct crypt_device *cd, FILE *wr, size_t bytes)
|
||||
{
|
||||
char block[bytes];
|
||||
size_t i;
|
||||
|
||||
if (fread(block, bytes, 1, wr) != 1) {
|
||||
log_dbg("EIO while reading spare area.");
|
||||
return -EIO;
|
||||
}
|
||||
for (i = 0; i < bytes; i++)
|
||||
if (block[i]) {
|
||||
log_err(cd, _("Spare area is not zeroed at position %" PRIu64 ".\n"),
|
||||
ftello(wr) - bytes);
|
||||
return -EPERM;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int verify_hash_block(const char *hash_name, int version,
|
||||
char *hash, size_t hash_size,
|
||||
const char *data, size_t data_size,
|
||||
const char *salt, size_t salt_size)
|
||||
{
|
||||
struct crypt_hash *ctx = NULL;
|
||||
int r;
|
||||
|
||||
if (crypt_hash_init(&ctx, hash_name))
|
||||
return -EINVAL;
|
||||
|
||||
if (version == 1 && (r = crypt_hash_write(ctx, salt, salt_size)))
|
||||
goto out;
|
||||
|
||||
if ((r = crypt_hash_write(ctx, data, data_size)))
|
||||
goto out;
|
||||
|
||||
if (version == 0 && (r = crypt_hash_write(ctx, salt, salt_size)))
|
||||
goto out;
|
||||
|
||||
r = crypt_hash_final(ctx, hash, hash_size);
|
||||
out:
|
||||
crypt_hash_destroy(ctx);
|
||||
return r;
|
||||
}
|
||||
|
||||
static int mult_overflow(off_t *u, off_t b, size_t size)
|
||||
{
|
||||
*u = (uint64_t)b * size;
|
||||
if ((off_t)(*u / size) != b || (off_t)*u < 0)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int create_or_verify(struct crypt_device *cd, FILE *rd, FILE *wr,
|
||||
off_t data_block, size_t data_block_size,
|
||||
off_t hash_block, size_t hash_block_size,
|
||||
off_t blocks, int version,
|
||||
const char *hash_name, int verify,
|
||||
char *calculated_digest, size_t digest_size,
|
||||
const char *salt, size_t salt_size)
|
||||
{
|
||||
char left_block[hash_block_size];
|
||||
char data_buffer[data_block_size];
|
||||
char read_digest[digest_size];
|
||||
size_t hash_per_block = 1 << get_bits_down(hash_block_size / digest_size);
|
||||
size_t digest_size_full = 1 << get_bits_up(digest_size);
|
||||
off_t blocks_to_write = (blocks + hash_per_block - 1) / hash_per_block;
|
||||
off_t seek_rd, seek_wr;
|
||||
size_t left_bytes;
|
||||
unsigned i;
|
||||
int r;
|
||||
|
||||
if (mult_overflow(&seek_rd, data_block, data_block_size) ||
|
||||
mult_overflow(&seek_wr, hash_block, hash_block_size)) {
|
||||
log_err(cd, _("Device offset overflow.\n"));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (fseeko(rd, seek_rd, SEEK_SET)) {
|
||||
log_dbg("Cannot seek to requested position in data device.");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (wr && fseeko(wr, seek_wr, SEEK_SET)) {
|
||||
log_dbg("Cannot seek to requested position in hash device.");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
memset(left_block, 0, hash_block_size);
|
||||
while (blocks_to_write--) {
|
||||
left_bytes = hash_block_size;
|
||||
for (i = 0; i < hash_per_block; i++) {
|
||||
if (!blocks)
|
||||
break;
|
||||
blocks--;
|
||||
if (fread(data_buffer, data_block_size, 1, rd) != 1) {
|
||||
log_dbg("Cannot read data device block.");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (verify_hash_block(hash_name, version,
|
||||
calculated_digest, digest_size,
|
||||
data_buffer, data_block_size,
|
||||
salt, salt_size))
|
||||
return -EINVAL;
|
||||
|
||||
if (!wr)
|
||||
break;
|
||||
if (verify) {
|
||||
if (fread(read_digest, digest_size, 1, wr) != 1) {
|
||||
log_dbg("Cannot read digest form hash device.");
|
||||
return -EIO;
|
||||
}
|
||||
if (memcmp(read_digest, calculated_digest, digest_size)) {
|
||||
log_err(cd, _("Verification failed at position %" PRIu64 ".\n"),
|
||||
ftello(rd) - data_block_size);
|
||||
return -EPERM;
|
||||
}
|
||||
} else {
|
||||
if (fwrite(calculated_digest, digest_size, 1, wr) != 1) {
|
||||
log_dbg("Cannot write digest to hash device.");
|
||||
return -EIO;
|
||||
}
|
||||
}
|
||||
if (version == 0) {
|
||||
left_bytes -= digest_size;
|
||||
} else {
|
||||
if (digest_size_full - digest_size) {
|
||||
if (verify) {
|
||||
r = verify_zero(cd, wr, digest_size_full - digest_size);
|
||||
if (r)
|
||||
return r;
|
||||
} else if (fwrite(left_block, digest_size_full - digest_size, 1, wr) != 1) {
|
||||
log_dbg("Cannot write spare area to hash device.");
|
||||
return -EIO;
|
||||
}
|
||||
}
|
||||
left_bytes -= digest_size_full;
|
||||
}
|
||||
}
|
||||
if (wr && left_bytes) {
|
||||
if (verify) {
|
||||
r = verify_zero(cd , wr, left_bytes);
|
||||
if (r)
|
||||
return r;
|
||||
} else if (fwrite(left_block, left_bytes, 1, wr) != 1) {
|
||||
log_dbg("Cannot write remaining spare area to hash device.");
|
||||
return -EIO;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int VERITY_create_or_verify_hash(struct crypt_device *cd,
|
||||
int verify,
|
||||
int version,
|
||||
const char *hash_name,
|
||||
const char *hash_device,
|
||||
const char *data_device,
|
||||
size_t hash_block_size,
|
||||
size_t data_block_size,
|
||||
off_t data_blocks,
|
||||
off_t hash_position,
|
||||
char *root_hash,
|
||||
size_t digest_size,
|
||||
const char *salt,
|
||||
size_t salt_size)
|
||||
{
|
||||
char calculated_digest[digest_size];
|
||||
FILE *data_file = NULL;
|
||||
FILE *hash_file = NULL, *hash_file_2;
|
||||
off_t hash_level_block[VERITY_MAX_LEVELS];
|
||||
off_t hash_level_size[VERITY_MAX_LEVELS];
|
||||
off_t data_file_blocks, s;
|
||||
size_t hash_per_block, hash_per_block_bits;
|
||||
off_t data_device_size = 0, hash_device_size = 0;
|
||||
uint64_t dev_size;
|
||||
int levels, i, r;
|
||||
|
||||
log_dbg("Hash %s %s, data device %s, data blocks %" PRIu64
|
||||
", hash_device %s, offset %" PRIu64 ".",
|
||||
verify ? "verification" : "creation", hash_name,
|
||||
data_device, data_blocks, hash_device, hash_position);
|
||||
|
||||
if (data_blocks < 0 || hash_position < 0) {
|
||||
log_err(cd, _("Invalid size parameters for verity device.\n"));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!data_blocks) {
|
||||
r = device_size(data_device, &dev_size);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
data_file_blocks = dev_size / data_block_size;
|
||||
} else
|
||||
data_file_blocks = data_blocks;
|
||||
|
||||
if (mult_overflow(&data_device_size, data_blocks, data_block_size)) {
|
||||
log_err(cd, _("Device offset overflow.\n"));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
hash_per_block_bits = get_bits_down(hash_block_size / digest_size);
|
||||
hash_per_block = 1 << hash_per_block_bits;
|
||||
if (!hash_per_block_bits)
|
||||
return -EINVAL;
|
||||
|
||||
levels = 0;
|
||||
if (data_file_blocks) {
|
||||
while (hash_per_block_bits * levels < 64 &&
|
||||
(data_file_blocks - 1) >> (hash_per_block_bits * levels))
|
||||
levels++;
|
||||
}
|
||||
log_dbg("Using %d hash levels.", levels);
|
||||
|
||||
if (levels > VERITY_MAX_LEVELS) {
|
||||
log_err(cd, _("Too many tree levels for verity volume.\n"));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (i = levels - 1; i >= 0; i--) {
|
||||
hash_level_block[i] = hash_position;
|
||||
// verity position of block data_file_blocks at level i
|
||||
s = data_file_blocks >> (i * hash_per_block_bits);
|
||||
s = (s + hash_per_block - 1) / hash_per_block;
|
||||
hash_level_size[i] = s;
|
||||
if (hash_position + s < hash_position ||
|
||||
(hash_position + s) < 0 ||
|
||||
(hash_position + s) != hash_position + s) {
|
||||
log_err(cd, _("Device offset overflow.\n"));
|
||||
return -EINVAL;
|
||||
}
|
||||
hash_position += s;
|
||||
}
|
||||
|
||||
if (mult_overflow(&hash_device_size, hash_position, hash_block_size)) {
|
||||
log_err(cd, _("Device offset overflow.\n"));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
log_dbg("Data device size required: %" PRIu64 " bytes.",
|
||||
data_device_size);
|
||||
data_file = fopen(data_device, "r");
|
||||
if (!data_file) {
|
||||
log_err(cd, _("Cannot open device %s.\n"), data_device);
|
||||
r = -EIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
log_dbg("Hash device size required: %" PRIu64 " bytes.",
|
||||
hash_device_size);
|
||||
hash_file = fopen(hash_device, verify ? "r" : "r+");
|
||||
if (!hash_file) {
|
||||
log_err(cd, _("Cannot open device %s.\n"), hash_device);
|
||||
r = -EIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
memset(calculated_digest, 0, digest_size);
|
||||
|
||||
for (i = 0; i < levels; i++) {
|
||||
if (!i) {
|
||||
r = create_or_verify(cd, data_file, hash_file,
|
||||
0, data_block_size,
|
||||
hash_level_block[i], hash_block_size,
|
||||
data_file_blocks, version, hash_name, verify,
|
||||
calculated_digest, digest_size, salt, salt_size);
|
||||
if (r)
|
||||
goto out;
|
||||
} else {
|
||||
hash_file_2 = fopen(hash_device, "r");
|
||||
if (!hash_file_2) {
|
||||
log_err(cd, _("Cannot open device %s.\n"), hash_device);
|
||||
r = -EIO;
|
||||
goto out;
|
||||
}
|
||||
r = create_or_verify(cd, hash_file_2, hash_file,
|
||||
hash_level_block[i - 1], hash_block_size,
|
||||
hash_level_block[i], hash_block_size,
|
||||
hash_level_size[i - 1], version, hash_name, verify,
|
||||
calculated_digest, digest_size, salt, salt_size);
|
||||
fclose(hash_file_2);
|
||||
if (r)
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (levels)
|
||||
r = create_or_verify(cd, hash_file, NULL,
|
||||
hash_level_block[levels - 1], hash_block_size,
|
||||
0, hash_block_size,
|
||||
1, version, hash_name, verify,
|
||||
calculated_digest, digest_size, salt, salt_size);
|
||||
else
|
||||
r = create_or_verify(cd, data_file, NULL,
|
||||
0, data_block_size,
|
||||
0, hash_block_size,
|
||||
data_file_blocks, version, hash_name, verify,
|
||||
calculated_digest, digest_size, salt, salt_size);
|
||||
out:
|
||||
if (verify) {
|
||||
if (r)
|
||||
log_err(cd, _("Verification of data area failed.\n"));
|
||||
else {
|
||||
log_dbg("Verification of data area succeeded.");
|
||||
r = memcmp(root_hash, calculated_digest, digest_size) ? -EPERM : 0;
|
||||
if (r)
|
||||
log_err(cd, _("Verification of root hash failed.\n"));
|
||||
else
|
||||
log_dbg("Verification of root hash succeeded.");
|
||||
}
|
||||
} else {
|
||||
if (r == -EIO)
|
||||
log_err(cd, _("Input/output error while creating hash area.\n"));
|
||||
else if (r)
|
||||
log_err(cd, _("Creation of hash area failed.\n"));
|
||||
else {
|
||||
fsync(fileno(hash_file));
|
||||
memcpy(root_hash, calculated_digest, digest_size);
|
||||
}
|
||||
}
|
||||
|
||||
if (data_file)
|
||||
fclose(data_file);
|
||||
if (hash_file)
|
||||
fclose(hash_file);
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Verify verity device using userspace crypto backend */
|
||||
int VERITY_verify(struct crypt_device *cd,
|
||||
struct crypt_params_verity *verity_hdr,
|
||||
const char *data_device,
|
||||
const char *hash_device,
|
||||
const char *root_hash,
|
||||
size_t root_hash_size)
|
||||
{
|
||||
return VERITY_create_or_verify_hash(cd, 1,
|
||||
verity_hdr->hash_type,
|
||||
verity_hdr->hash_name,
|
||||
hash_device,
|
||||
data_device,
|
||||
verity_hdr->hash_block_size,
|
||||
verity_hdr->data_block_size,
|
||||
verity_hdr->data_size,
|
||||
VERITY_hash_offset_block(verity_hdr),
|
||||
CONST_CAST(char*)root_hash,
|
||||
root_hash_size,
|
||||
verity_hdr->salt,
|
||||
verity_hdr->salt_size);
|
||||
}
|
||||
|
||||
/* Create verity hash */
|
||||
int VERITY_create(struct crypt_device *cd,
|
||||
struct crypt_params_verity *verity_hdr,
|
||||
const char *data_device,
|
||||
const char *hash_device,
|
||||
char *root_hash,
|
||||
size_t root_hash_size)
|
||||
{
|
||||
unsigned pgsize = crypt_getpagesize();
|
||||
|
||||
if (verity_hdr->salt_size > 256)
|
||||
return -EINVAL;
|
||||
|
||||
if (verity_hdr->data_block_size > pgsize)
|
||||
log_err(cd, _("WARNING: Kernel cannot activate device if data "
|
||||
"block size exceeds page size (%u).\n"), pgsize);
|
||||
|
||||
return VERITY_create_or_verify_hash(cd, 0,
|
||||
verity_hdr->hash_type,
|
||||
verity_hdr->hash_name,
|
||||
hash_device,
|
||||
data_device,
|
||||
verity_hdr->hash_block_size,
|
||||
verity_hdr->data_block_size,
|
||||
verity_hdr->data_size,
|
||||
VERITY_hash_offset_block(verity_hdr),
|
||||
root_hash,
|
||||
root_hash_size,
|
||||
verity_hdr->salt,
|
||||
verity_hdr->salt_size);
|
||||
}
|
||||
66
lib/volumekey.c
Normal file
66
lib/volumekey.c
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* cryptsetup volume key implementation
|
||||
*
|
||||
* Copyright (C) 2004-2006, Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Copyright (C) 2010-2012, 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
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
struct volume_key *crypt_alloc_volume_key(unsigned keylength, const char *key)
|
||||
{
|
||||
struct volume_key *vk = malloc(sizeof(*vk) + keylength);
|
||||
|
||||
if (!vk)
|
||||
return NULL;
|
||||
|
||||
vk->keylength = keylength;
|
||||
if (key)
|
||||
memcpy(&vk->key, key, keylength);
|
||||
else
|
||||
memset(&vk->key, 0, keylength);
|
||||
|
||||
return vk;
|
||||
}
|
||||
|
||||
void crypt_free_volume_key(struct volume_key *vk)
|
||||
{
|
||||
if (vk) {
|
||||
memset(vk->key, 0, vk->keylength);
|
||||
vk->keylength = 0;
|
||||
free(vk);
|
||||
}
|
||||
}
|
||||
|
||||
struct volume_key *crypt_generate_volume_key(struct crypt_device *cd, unsigned keylength)
|
||||
{
|
||||
int r;
|
||||
struct volume_key *vk;
|
||||
|
||||
vk = crypt_alloc_volume_key(keylength, NULL);
|
||||
if (!vk)
|
||||
return NULL;
|
||||
|
||||
r = crypt_random_get(cd, vk->key, keylength, CRYPT_RND_KEY);
|
||||
if(r < 0) {
|
||||
crypt_free_volume_key(vk);
|
||||
return NULL;
|
||||
}
|
||||
return vk;
|
||||
}
|
||||
178
luks/Makefile.am
178
luks/Makefile.am
@@ -1,178 +0,0 @@
|
||||
moduledir = $(libdir)/cryptsetup
|
||||
|
||||
noinst_LTLIBRARIES = libluks.la
|
||||
|
||||
libluks_la_CFLAGS = -I $(top_srcdir)/luks/sha -Wall
|
||||
|
||||
libluks_la_SOURCES = \
|
||||
af.c \
|
||||
pbkdf.c \
|
||||
keymanage.c \
|
||||
keyencryption.c \
|
||||
hexprint.c \
|
||||
random.c \
|
||||
sha/sha1.c \
|
||||
sha/hmac_sha1.h \
|
||||
sha/hmac.h \
|
||||
sha/hmac_sha1.c \
|
||||
sha/sha1.h \
|
||||
XORblock.h \
|
||||
pbkdf.h \
|
||||
random.h \
|
||||
af.h \
|
||||
luks.h
|
||||
|
||||
INCLUDES = -D_GNU_SOURCE \
|
||||
-D_LARGEFILE64_SOURCE \
|
||||
-D_FILE_OFFSET_BITS=64 \
|
||||
-I$(top_srcdir)/lib
|
||||
|
||||
EXTRA_DIST = sha/hmac.c testing/fileDiffer.py testing/compatimage.bz2
|
||||
|
||||
ORIG_IMG = /tmp/luks-test-orig
|
||||
IMG = /tmp/luks-test
|
||||
IMG1 = /tmp/luks-test1
|
||||
|
||||
|
||||
LUKS_HEADER = S0-5 S6-7 S8-39 S40-71 S72-103 S104-107 S108-111 R112-131 R132-163 S164-167 S168-207 A0-591
|
||||
|
||||
KEY_SLOT0 = S208-211 S212-215 R216-247 S248-251 S251-255
|
||||
KEY_MATERIAL0 = R4096-68096
|
||||
KEY_MATERIAL0_EXT = R4096-68096
|
||||
|
||||
KEY_SLOT1 = S256-259 S260-263 R264-295 S296-299 S300-303
|
||||
KEY_MATERIAL1 = R69632-133632
|
||||
KEY_MATERIAL1_EXT = S69632-133632
|
||||
|
||||
LOOPDEV = /dev/loop/5
|
||||
|
||||
test:
|
||||
(cd ..; make clean; make CFLAGS=-Werror)
|
||||
@if [ `id -u` != 0 ]; then \
|
||||
echo Not root; \
|
||||
fi
|
||||
@if [ ! -e /tmp/key1 ]; then \
|
||||
dd if=/dev/urandom of=/tmp/key1 count=1 bs=32; \
|
||||
fi
|
||||
@bzip2 -cd testing/compatimage.bz2 > $(IMG)
|
||||
@-/sbin/losetup -d $(LOOPDEV)
|
||||
@/sbin/losetup $(LOOPDEV) $(IMG)
|
||||
|
||||
@echo Case: open - compat image - acceptance check
|
||||
# Image must not change
|
||||
@cp $(IMG) $(ORIG_IMG)
|
||||
echo "compatkey" | ../src/cryptsetup -v luksOpen $(LOOPDEV) dummy
|
||||
@sync
|
||||
testing/fileDiffer.py $(IMG) $(ORIG_IMG)
|
||||
@-ls -l /dev/mapper/dummy > /dev/null
|
||||
@../src/cryptsetup remove dummy
|
||||
@echo "success"
|
||||
|
||||
|
||||
@echo Case: open - compat image - denial check
|
||||
# Image must not change
|
||||
@cp $(IMG) $(ORIG_IMG)
|
||||
echo "wrongkey" | ../src/cryptsetup -v luksOpen $(LOOPDEV) dummy || true
|
||||
@sync
|
||||
testing/fileDiffer.py $(IMG) $(ORIG_IMG)
|
||||
@echo "success"
|
||||
|
||||
@echo Case: format
|
||||
# All headers items and first key material section must change
|
||||
@cp $(IMG) $(ORIG_IMG)
|
||||
echo "key0" | ../src/cryptsetup -v -i 1000 -c aes-cbc-essiv:sha256 luksFormat $(LOOPDEV)
|
||||
@sync
|
||||
testing/fileDiffer.py $(IMG) $(ORIG_IMG) $(LUKS_HEADER) $(KEY_SLOT0) $(KEY_MATERIAL0)
|
||||
|
||||
@echo Case: open
|
||||
# Image must not change
|
||||
@cp $(IMG) $(ORIG_IMG)
|
||||
echo "key0" | ../src/cryptsetup -v luksOpen $(LOOPDEV) dummy
|
||||
@sync
|
||||
testing/fileDiffer.py $(IMG) $(ORIG_IMG)
|
||||
@-ls -l /dev/mapper/dummy > /dev/null
|
||||
@../src/cryptsetup remove dummy
|
||||
@echo "success"
|
||||
|
||||
@echo Case: add key
|
||||
# Key Slot 1 and key material section 1 must change, the rest must not.
|
||||
@cp $(IMG) $(ORIG_IMG)
|
||||
echo -e "key0\nkey1" | ../src/cryptsetup -v luksAddKey $(LOOPDEV)
|
||||
@sync
|
||||
testing/fileDiffer.py $(IMG) $(ORIG_IMG) $(KEY_SLOT1) $(KEY_MATERIAL1)
|
||||
echo "key1" | ../src/cryptsetup -v luksOpen $(LOOPDEV) dummy
|
||||
@-ls -l /dev/mapper/dummy > /dev/null
|
||||
@../src/cryptsetup -v remove dummy
|
||||
@echo "success"
|
||||
|
||||
# Unsuccessful Key Delete - nothing may change
|
||||
@echo Case: unsuccessful delete
|
||||
@cp $(IMG) $(ORIG_IMG)
|
||||
echo "invalid" | ../src/cryptsetup -v luksDelKey $(LOOPDEV) 1 || true
|
||||
@sync
|
||||
testing/fileDiffer.py $(IMG) $(ORIG_IMG)
|
||||
@echo "success"
|
||||
|
||||
# Delete Key Test
|
||||
# Key Slot 1 and key material section 1 must change, the rest must not
|
||||
@echo Case: successful delete
|
||||
@cp $(IMG) $(ORIG_IMG)
|
||||
../src/cryptsetup -v -q luksDelKey $(LOOPDEV) 1
|
||||
@sync
|
||||
testing/fileDiffer.py $(IMG) $(ORIG_IMG) $(KEY_SLOT1) $(KEY_MATERIAL1_EXT)
|
||||
echo "key1" | ../src/cryptsetup -v luksOpen $(LOOPDEV) dummy 2>/dev/null || true
|
||||
echo "key0" | ../src/cryptsetup -v luksOpen $(LOOPDEV) dummy 2>/dev/null
|
||||
@../src/cryptsetup -v remove dummy
|
||||
@echo "success"
|
||||
|
||||
# Non-Exclusive Open test
|
||||
@echo Case: Non-Exclusive Open
|
||||
echo "key0" | ../src/cryptsetup -v --readonly luksOpen $(LOOPDEV) dummy1 2>/dev/null
|
||||
# must fail
|
||||
echo "key0" | ../src/cryptsetup -v --readonly luksOpen $(LOOPDEV) dummy2 2>/dev/null || true
|
||||
echo "key0" | ../src/cryptsetup -v --non-exclusive --readonly luksOpen $(LOOPDEV) dummy2 2>/dev/null
|
||||
@../src/cryptsetup -v remove dummy1
|
||||
@../src/cryptsetup -v remove dummy2
|
||||
|
||||
|
||||
# Key Slot 1 and key material section 1 must change, the rest must not
|
||||
@echo Case: add key test for key files
|
||||
@cp $(IMG) $(ORIG_IMG)
|
||||
echo "key0" | ../src/cryptsetup -v luksAddKey $(LOOPDEV) /tmp/key1
|
||||
@sync
|
||||
testing/fileDiffer.py $(IMG) $(ORIG_IMG) $(KEY_SLOT1) $(KEY_MATERIAL1)
|
||||
../src/cryptsetup -d /tmp/key1 -v luksOpen $(LOOPDEV) dummy
|
||||
@-ls -l /dev/mapper/dummy > /dev/null
|
||||
@../src/cryptsetup -v remove dummy
|
||||
@echo "success"
|
||||
|
||||
@echo Case: delete key test with /tmp/key1 as remaining key
|
||||
# Key Slot 1 and key material section 1 must change, the rest must not
|
||||
@cp $(IMG) $(ORIG_IMG)
|
||||
../src/cryptsetup -v -d /tmp/key1 luksDelKey $(LOOPDEV) 0
|
||||
@sync
|
||||
testing/fileDiffer.py $(IMG) $(ORIG_IMG) $(KEY_SLOT0) $(KEY_MATERIAL0_EXT)
|
||||
echo "key0" | ../src/cryptsetup -v luksOpen $(LOOPDEV) dummy 2>/dev/null || true
|
||||
../src/cryptsetup -v luksOpen -d /tmp/key1 $(LOOPDEV) dummy 2>/dev/null
|
||||
@../src/cryptsetup -v remove dummy
|
||||
@echo "success"
|
||||
|
||||
# Delete last slot
|
||||
@echo Case: delete last key
|
||||
@cp $(IMG) $(ORIG_IMG)
|
||||
@echo "key0" | ../src/cryptsetup -v luksFormat $(LOOPDEV)
|
||||
echo "key0" | ../src/cryptsetup -v luksKillSlot $(LOOPDEV) 0
|
||||
@sync
|
||||
echo "key0" | ../src/cryptsetup -v luksOpen $(LOOPDEV) dummy 2>/dev/null || true
|
||||
@echo "success"
|
||||
|
||||
# Format test for ESSIV, and some other parameters.
|
||||
@echo Case: parameter variation test
|
||||
@dd if=/dev/zero of=$(IMG) count=20000
|
||||
@cp $(IMG) $(ORIG_IMG)
|
||||
@../src/cryptsetup -q -v -i 1000 -c aes-cbc-essiv:sha256 luksFormat $(LOOPDEV) /tmp/key1
|
||||
@sync
|
||||
testing/fileDiffer.py $(IMG) $(ORIG_IMG) $(LUKS_HEADER) $(KEY_SLOT0) $(KEY_MATERIAL0)
|
||||
@../src/cryptsetup -d /tmp/key1 -v luksOpen $(LOOPDEV) dummy
|
||||
@-ls -l /dev/mapper/dummy > /dev/null && echo "success"
|
||||
@../src/cryptsetup -v remove dummy
|
||||
@@ -1,13 +0,0 @@
|
||||
#ifndef INCLUDED_CRYPTSETUP_LUKS_XORBLOCK_H
|
||||
#define INCLUDED_CRYPTSETUP_LUKS_XORBLOCK_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
static void inline XORblock(char const *src1, char const *src2, char *dst, size_t n)
|
||||
{
|
||||
size_t j;
|
||||
for(j = 0; j < n; ++j)
|
||||
dst[j] = src1[j] ^ src2[j];
|
||||
}
|
||||
|
||||
#endif
|
||||
116
luks/af.c
116
luks/af.c
@@ -1,116 +0,0 @@
|
||||
/*
|
||||
* AFsplitter - Anti forensic information splitter
|
||||
* Copyright 2004, Clemens Fruhwirth <clemens@endorphin.org>
|
||||
*
|
||||
* AFsplitter diffuses information over a large stripe of data,
|
||||
* therefor 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
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <netinet/in.h>
|
||||
#include <errno.h>
|
||||
#include "sha1.h"
|
||||
#include "XORblock.h"
|
||||
#include "random.h"
|
||||
|
||||
/* diffuse: Information spreading over the whole dataset with
|
||||
* the help of sha512.
|
||||
*/
|
||||
|
||||
static void diffuse(unsigned char *src, unsigned char *dst, size_t size)
|
||||
{
|
||||
sha1_ctx ctx;
|
||||
uint32_t i;
|
||||
uint32_t IV; /* host byte order independend hash IV */
|
||||
|
||||
unsigned int fullblocks = size / SHA1_DIGEST_SIZE;
|
||||
unsigned int padding = size % SHA1_DIGEST_SIZE;
|
||||
unsigned char final[SHA1_DIGEST_SIZE];
|
||||
|
||||
/* hash block the whole data set with different IVs to produce
|
||||
* more than just a single data block
|
||||
*/
|
||||
for (i=0; i < fullblocks; i++) {
|
||||
sha1_begin(&ctx);
|
||||
IV = htonl(i);
|
||||
sha1_hash((const unsigned char *) &IV, sizeof(IV), &ctx);
|
||||
sha1_hash(src + SHA1_DIGEST_SIZE * i, SHA1_DIGEST_SIZE, &ctx);
|
||||
sha1_end(dst + SHA1_DIGEST_SIZE * i, &ctx);
|
||||
}
|
||||
|
||||
if(padding) {
|
||||
sha1_begin(&ctx);
|
||||
IV = htonl(i);
|
||||
sha1_hash((const unsigned char *) &IV, sizeof(IV), &ctx);
|
||||
sha1_hash(src + SHA1_DIGEST_SIZE * i, padding, &ctx);
|
||||
sha1_end(final, &ctx);
|
||||
memcpy(dst + SHA1_DIGEST_SIZE * i, final, padding);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Information splitting. The amount of data is multiplied by
|
||||
* blocknumbers. The same blocksize and blocknumbers values
|
||||
* must be supplied to AF_merge to recover information.
|
||||
*/
|
||||
|
||||
int AF_split(char *src, char *dst, size_t blocksize, unsigned int blocknumbers)
|
||||
{
|
||||
unsigned int i;
|
||||
char *bufblock;
|
||||
int r = -EINVAL;
|
||||
|
||||
if((bufblock = calloc(blocksize, 1)) == NULL) return -ENOMEM;
|
||||
|
||||
/* process everything except the last block */
|
||||
for(i=0; i<blocknumbers-1; i++) {
|
||||
r = getRandom(dst+(blocksize*i),blocksize);
|
||||
if(r < 0) goto out;
|
||||
|
||||
XORblock(dst+(blocksize*i),bufblock,bufblock,blocksize);
|
||||
diffuse((unsigned char *) bufblock, (unsigned char *) bufblock, blocksize);
|
||||
}
|
||||
/* the last block is computed */
|
||||
XORblock(src,bufblock,dst+(i*blocksize),blocksize);
|
||||
r = 0;
|
||||
out:
|
||||
free(bufblock);
|
||||
return r;
|
||||
}
|
||||
|
||||
int AF_merge(char *src, char *dst, size_t blocksize, unsigned int blocknumbers)
|
||||
{
|
||||
unsigned int i;
|
||||
char *bufblock;
|
||||
|
||||
if((bufblock = calloc(blocksize, 1)) == NULL) return -ENOMEM;
|
||||
|
||||
memset(bufblock,0,blocksize);
|
||||
for(i=0; i<blocknumbers-1; i++) {
|
||||
XORblock(src+(blocksize*i),bufblock,bufblock,blocksize);
|
||||
diffuse((unsigned char *) bufblock, (unsigned char *) bufblock, blocksize);
|
||||
}
|
||||
XORblock(src + blocksize * i, bufblock, dst, blocksize);
|
||||
|
||||
free(bufblock);
|
||||
return 0;
|
||||
}
|
||||
25
luks/af.h
25
luks/af.h
@@ -1,25 +0,0 @@
|
||||
#ifndef INCLUDED_CRYPTSETUP_LUKS_AF_H
|
||||
#define INCLUDED_CRYPTSETUP_LUKS_AF_H
|
||||
|
||||
/*
|
||||
* AFsplitter - Anti forensic information splitter
|
||||
* Copyright 2004, Clemens Fruhwirth <clemens@endorphin.org>
|
||||
*/
|
||||
|
||||
/*
|
||||
* AF_split operates on src and produces information splitted data in
|
||||
* dst. src is assumed to be of the length blocksize. The data stripe
|
||||
* dst points to must be captable of storing blocksize*blocknumbers.
|
||||
* blocknumbers is the data multiplication factor.
|
||||
*
|
||||
* AF_merge does just the opposite: reproduces the information stored in
|
||||
* src of the length blocksize*blocknumbers into dst of the length
|
||||
* blocksize.
|
||||
*
|
||||
* On error, both functions return -1, 0 otherwise.
|
||||
*/
|
||||
|
||||
int AF_split(char *src, char *dst, size_t blocksize, unsigned int blocknumbers);
|
||||
int AF_merge(char *src, char *dst, size_t blocksize, unsigned int blocknumbers);
|
||||
|
||||
#endif
|
||||
@@ -1,12 +0,0 @@
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
void hexprint(char *d, int n)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < n; i++)
|
||||
{
|
||||
printf("%02hhx ", (char)d[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,232 +0,0 @@
|
||||
/*
|
||||
* LUKS - Linux Unified Key Setup
|
||||
*
|
||||
* Copyright (C) 2004-2006, Clemens Fruhwirth <clemens@endorphin.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <inttypes.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/utsname.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include "luks.h"
|
||||
#include "../lib/libcryptsetup.h"
|
||||
#include "../lib/internal.h"
|
||||
#include "../lib/blockdev.h"
|
||||
|
||||
#define div_round_up(a,b) ({ \
|
||||
typeof(a) __a = (a); \
|
||||
typeof(b) __b = (b); \
|
||||
(__a - 1) / __b + 1; \
|
||||
})
|
||||
|
||||
static inline int round_up_modulo(int x, int m) {
|
||||
return div_round_up(x, m) * m;
|
||||
}
|
||||
|
||||
static struct setup_backend *cleaner_backend=NULL;
|
||||
static const char *cleaner_name=NULL;
|
||||
static uint64_t cleaner_size = 0;
|
||||
static int devfd=-1;
|
||||
|
||||
static int setup_mapping(const char *cipher, const char *name,
|
||||
const char *device, unsigned int payloadOffset,
|
||||
const char *key, size_t keyLength,
|
||||
unsigned int sector, size_t srcLength,
|
||||
struct setup_backend *backend,
|
||||
int mode)
|
||||
{
|
||||
struct crypt_options k = {0};
|
||||
struct crypt_options *options = &k;
|
||||
int device_sector_size = sector_size_for_device(device);
|
||||
int r;
|
||||
|
||||
/*
|
||||
* we need to round this to nearest multiple of the underlying
|
||||
* device's sector size, otherwise the mapping will be refused.
|
||||
*/
|
||||
if(device_sector_size < 0) {
|
||||
set_error(_("Unable to obtain sector size for %s"),device);
|
||||
return -EINVAL;
|
||||
}
|
||||
options->size = round_up_modulo(srcLength,device_sector_size)/SECTOR_SIZE;
|
||||
cleaner_size = options->size;
|
||||
|
||||
options->offset = sector;
|
||||
options->cipher = cipher;
|
||||
options->key_size = keyLength;
|
||||
options->skip = 0;
|
||||
options->flags = 0;
|
||||
options->name = name;
|
||||
options->device = device;
|
||||
|
||||
if (mode == O_RDONLY) {
|
||||
options->flags |= CRYPT_FLAG_READONLY;
|
||||
}
|
||||
|
||||
set_error(NULL);
|
||||
|
||||
r = backend->create(0, options, key, NULL);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int clear_mapping(const char *name, uint64_t size, struct setup_backend *backend)
|
||||
{
|
||||
struct crypt_options options = {0};
|
||||
options.name=name;
|
||||
options.size = size;
|
||||
return backend->remove(1, &options);
|
||||
}
|
||||
|
||||
static void sigint_handler(int sig)
|
||||
{
|
||||
if(devfd >= 0)
|
||||
close(devfd);
|
||||
devfd = -1;
|
||||
if(cleaner_backend && cleaner_name)
|
||||
clear_mapping(cleaner_name, cleaner_size, cleaner_backend);
|
||||
signal(SIGINT, SIG_DFL);
|
||||
kill(getpid(), SIGINT);
|
||||
}
|
||||
|
||||
static char *_error_hint(char *cipherName, char *cipherMode, size_t keyLength)
|
||||
{
|
||||
char *hint = "";
|
||||
#ifdef __linux__
|
||||
char c, tmp[4] = {0};
|
||||
struct utsname uts;
|
||||
int i = 0, kernel_minor;
|
||||
|
||||
/* Nothing to suggest here */
|
||||
if (uname(&uts) || strncmp(uts.release, "2.6.", 4))
|
||||
return hint;
|
||||
|
||||
/* Get kernel minor without suffixes */
|
||||
while (i < 3 && (c = uts.release[i + 4]))
|
||||
tmp[i++] = isdigit(c) ? c : '\0';
|
||||
kernel_minor = atoi(tmp);
|
||||
|
||||
if (!strncmp(cipherMode, "xts", 3) && (keyLength != 256 && keyLength != 512))
|
||||
hint = "Key size in XTS mode must be 256 or 512 bits.";
|
||||
else if (!strncmp(cipherMode, "xts", 3) && kernel_minor < 24)
|
||||
hint = "Block mode XTS is available since kernel 2.6.24.";
|
||||
if (!strncmp(cipherMode, "lrw", 3) && (keyLength != 256 && keyLength != 512))
|
||||
hint = "Key size in LRW mode must be 256 or 512 bits.";
|
||||
else if (!strncmp(cipherMode, "lrw", 3) && kernel_minor < 20)
|
||||
hint = "Block mode LRW is available since kernel 2.6.20.";
|
||||
#endif
|
||||
return hint;
|
||||
}
|
||||
|
||||
/* This function is not reentrant safe, as it installs a signal
|
||||
handler and global vars for cleaning */
|
||||
static int LUKS_endec_template(char *src, size_t srcLength,
|
||||
struct luks_phdr *hdr,
|
||||
char *key, size_t keyLength,
|
||||
const char *device,
|
||||
unsigned int sector, struct setup_backend *backend,
|
||||
ssize_t (*func)(int, void *, size_t),
|
||||
int mode)
|
||||
{
|
||||
char *name = NULL;
|
||||
char *fullpath = NULL;
|
||||
char *dmCipherSpec = NULL;
|
||||
const char *dmDir = backend->dir();
|
||||
int r = -1;
|
||||
|
||||
if(dmDir == NULL) {
|
||||
fputs(_("Failed to obtain device mapper directory."), stderr);
|
||||
return -1;
|
||||
}
|
||||
if(asprintf(&name,"temporary-cryptsetup-%d",getpid()) == -1 ||
|
||||
asprintf(&fullpath,"%s/%s",dmDir,name) == -1 ||
|
||||
asprintf(&dmCipherSpec,"%s-%s",hdr->cipherName, hdr->cipherMode) == -1) {
|
||||
r = -ENOMEM;
|
||||
goto out1;
|
||||
}
|
||||
|
||||
signal(SIGINT, sigint_handler);
|
||||
cleaner_name = name;
|
||||
cleaner_backend = backend;
|
||||
|
||||
r = setup_mapping(dmCipherSpec,name,device,hdr->payloadOffset,key,keyLength,sector,srcLength,backend,mode);
|
||||
if(r < 0) {
|
||||
set_error("Failed to setup dm-crypt key mapping for device %s.\n"
|
||||
"Check that kernel supports %s cipher (check syslog for more info).\n%s",
|
||||
device, dmCipherSpec,
|
||||
_error_hint(hdr->cipherName, hdr->cipherMode, keyLength * 8));
|
||||
r = -EIO;
|
||||
goto out1;
|
||||
}
|
||||
|
||||
devfd = open(fullpath, mode | O_DIRECT | O_SYNC); /* devfd is a global var */
|
||||
if(devfd == -1) { r = -EIO; goto out2; }
|
||||
|
||||
r = func(devfd,src,srcLength);
|
||||
if(r < 0) { r = -EIO; goto out3; }
|
||||
|
||||
r = 0;
|
||||
out3:
|
||||
close(devfd);
|
||||
devfd = -1;
|
||||
out2:
|
||||
clear_mapping(cleaner_name, cleaner_size, cleaner_backend);
|
||||
out1:
|
||||
signal(SIGINT, SIG_DFL);
|
||||
cleaner_name = NULL;
|
||||
cleaner_backend = NULL;
|
||||
cleaner_size = 0;
|
||||
free(dmCipherSpec);
|
||||
free(fullpath);
|
||||
free(name);
|
||||
return r;
|
||||
}
|
||||
|
||||
int LUKS_encrypt_to_storage(char *src, size_t srcLength,
|
||||
struct luks_phdr *hdr,
|
||||
char *key, size_t keyLength,
|
||||
const char *device,
|
||||
unsigned int sector, struct setup_backend *backend)
|
||||
{
|
||||
|
||||
return LUKS_endec_template(src,srcLength,hdr,key,keyLength, device, sector, backend,
|
||||
(ssize_t (*)(int, void *, size_t)) write_blockwise, O_RDWR);
|
||||
}
|
||||
|
||||
int LUKS_decrypt_from_storage(char *dst, size_t dstLength,
|
||||
struct luks_phdr *hdr,
|
||||
char *key, size_t keyLength,
|
||||
const char *device,
|
||||
unsigned int sector, struct setup_backend *backend)
|
||||
{
|
||||
return LUKS_endec_template(dst,dstLength,hdr,key,keyLength, device, sector, backend, read_blockwise, O_RDONLY);
|
||||
}
|
||||
|
||||
// Local Variables:
|
||||
// c-basic-offset: 8
|
||||
// indent-tabs-mode: nil
|
||||
// End:
|
||||
523
luks/keymanage.c
523
luks/keymanage.c
@@ -1,523 +0,0 @@
|
||||
/*
|
||||
* LUKS - Linux Unified Key Setup
|
||||
*
|
||||
* Copyright (C) 2004-2006, Clemens Fruhwirth <clemens@endorphin.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/fs.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "luks.h"
|
||||
#include "af.h"
|
||||
#include "pbkdf.h"
|
||||
#include "sha1.h"
|
||||
#include "random.h"
|
||||
#include "XORblock.h"
|
||||
#include <uuid/uuid.h>
|
||||
#include <../lib/internal.h>
|
||||
|
||||
#define div_round_up(a,b) ({ \
|
||||
typeof(a) __a = (a); \
|
||||
typeof(b) __b = (b); \
|
||||
(__a - 1) / __b + 1; \
|
||||
})
|
||||
|
||||
static inline int round_up_modulo(int x, int m) {
|
||||
return div_round_up(x, m) * m;
|
||||
}
|
||||
|
||||
struct luks_masterkey *LUKS_alloc_masterkey(int keylength)
|
||||
{
|
||||
struct luks_masterkey *mk=malloc(sizeof(*mk) + keylength);
|
||||
if(NULL == mk) return NULL;
|
||||
mk->keyLength=keylength;
|
||||
return mk;
|
||||
}
|
||||
|
||||
void LUKS_dealloc_masterkey(struct luks_masterkey *mk)
|
||||
{
|
||||
if(NULL != mk) {
|
||||
memset(mk->key,0,mk->keyLength);
|
||||
mk->keyLength=0;
|
||||
free(mk);
|
||||
}
|
||||
}
|
||||
|
||||
struct luks_masterkey *LUKS_generate_masterkey(int keylength)
|
||||
{
|
||||
struct luks_masterkey *mk=LUKS_alloc_masterkey(keylength);
|
||||
if(NULL == mk) return NULL;
|
||||
|
||||
int r = getRandom(mk->key,keylength);
|
||||
if(r < 0) {
|
||||
LUKS_dealloc_masterkey(mk);
|
||||
return NULL;
|
||||
}
|
||||
return mk;
|
||||
}
|
||||
|
||||
int LUKS_read_phdr(const char *device, struct luks_phdr *hdr)
|
||||
{
|
||||
int devfd = 0, r = 0;
|
||||
unsigned int i;
|
||||
uint64_t size;
|
||||
char luksMagic[] = LUKS_MAGIC;
|
||||
|
||||
devfd = open(device,O_RDONLY | O_DIRECT | O_SYNC);
|
||||
if(-1 == devfd) {
|
||||
set_error(_("Can't open device: %s\n"), device);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if(read_blockwise(devfd, hdr, sizeof(struct luks_phdr)) < sizeof(struct luks_phdr)) {
|
||||
r = -EIO;
|
||||
} else if(memcmp(hdr->magic, luksMagic, LUKS_MAGIC_L)) { /* Check magic */
|
||||
set_error(_("%s is not a LUKS partition\n"), device);
|
||||
r = -EINVAL;
|
||||
} else if(memcmp(hdr->hashSpec, "sha1", 4)) { /* Check for SHA1 - other hashspecs are not implemented ATM */
|
||||
set_error(_("unknown hash spec in phdr\n"), stderr);
|
||||
r = -EINVAL;
|
||||
} else if((hdr->version = ntohs(hdr->version)) != 1) { /* Convert every uint16/32_t item from network byte order */
|
||||
set_error(_("unknown LUKS version %d\n"), hdr->version);
|
||||
r = -EINVAL;
|
||||
} else {
|
||||
hdr->payloadOffset = ntohl(hdr->payloadOffset);
|
||||
hdr->keyBytes = ntohl(hdr->keyBytes);
|
||||
hdr->mkDigestIterations = ntohl(hdr->mkDigestIterations);
|
||||
|
||||
for(i = 0; i < LUKS_NUMKEYS; ++i) {
|
||||
hdr->keyblock[i].active = ntohl(hdr->keyblock[i].active);
|
||||
hdr->keyblock[i].passwordIterations = ntohl(hdr->keyblock[i].passwordIterations);
|
||||
hdr->keyblock[i].keyMaterialOffset = ntohl(hdr->keyblock[i].keyMaterialOffset);
|
||||
hdr->keyblock[i].stripes = ntohl(hdr->keyblock[i].stripes);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BLKGETSIZE64
|
||||
if (ioctl(devfd, BLKGETSIZE64, &size) < 0 ||
|
||||
size < (uint64_t)hdr->payloadOffset) {
|
||||
set_error(_("LUKS header detected but device %s is too small.\n"), device);
|
||||
r = -EINVAL;
|
||||
}
|
||||
#endif
|
||||
close(devfd);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int LUKS_write_phdr(const char *device, struct luks_phdr *hdr)
|
||||
{
|
||||
int devfd = 0;
|
||||
unsigned int i;
|
||||
struct luks_phdr convHdr;
|
||||
int r;
|
||||
|
||||
devfd = open(device,O_RDWR | O_DIRECT | O_SYNC);
|
||||
if(-1 == devfd) {
|
||||
set_error(_("Can't open device %s"), device);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
memcpy(&convHdr, hdr, sizeof(struct luks_phdr));
|
||||
|
||||
/* Convert every uint16/32_t item to network byte order */
|
||||
convHdr.version = htons(hdr->version);
|
||||
convHdr.payloadOffset = htonl(hdr->payloadOffset);
|
||||
convHdr.keyBytes = htonl(hdr->keyBytes);
|
||||
convHdr.mkDigestIterations = htonl(hdr->mkDigestIterations);
|
||||
for(i = 0; i < LUKS_NUMKEYS; ++i) {
|
||||
convHdr.keyblock[i].active = htonl(hdr->keyblock[i].active);
|
||||
convHdr.keyblock[i].passwordIterations = htonl(hdr->keyblock[i].passwordIterations);
|
||||
convHdr.keyblock[i].keyMaterialOffset = htonl(hdr->keyblock[i].keyMaterialOffset);
|
||||
convHdr.keyblock[i].stripes = htonl(hdr->keyblock[i].stripes);
|
||||
}
|
||||
|
||||
r = write_blockwise(devfd, &convHdr, sizeof(struct luks_phdr)) < sizeof(struct luks_phdr) ? -EIO : 0;
|
||||
|
||||
close(devfd);
|
||||
return r;
|
||||
}
|
||||
|
||||
int LUKS_generate_phdr(struct luks_phdr *header,
|
||||
const struct luks_masterkey *mk, const char *cipherName,
|
||||
const char *cipherMode, unsigned int stripes,
|
||||
unsigned int alignPayload)
|
||||
{
|
||||
unsigned int i=0;
|
||||
unsigned int blocksPerStripeSet = div_round_up(mk->keyLength*stripes,SECTOR_SIZE);
|
||||
int r;
|
||||
char luksMagic[] = LUKS_MAGIC;
|
||||
uuid_t partitionUuid;
|
||||
int currentSector;
|
||||
int alignSectors = 4096/SECTOR_SIZE;
|
||||
if (alignPayload == 0)
|
||||
alignPayload = alignSectors;
|
||||
|
||||
memset(header,0,sizeof(struct luks_phdr));
|
||||
|
||||
/* Set Magic */
|
||||
memcpy(header->magic,luksMagic,LUKS_MAGIC_L);
|
||||
header->version=1;
|
||||
strncpy(header->cipherName,cipherName,LUKS_CIPHERNAME_L);
|
||||
strncpy(header->cipherMode,cipherMode,LUKS_CIPHERMODE_L);
|
||||
|
||||
/* This is hard coded ATM */
|
||||
strncpy(header->hashSpec,"sha1",LUKS_HASHSPEC_L);
|
||||
|
||||
header->keyBytes=mk->keyLength;
|
||||
|
||||
r = getRandom(header->mkDigestSalt,LUKS_SALTSIZE);
|
||||
if(r < 0) return r;
|
||||
|
||||
/* Compute master key digest */
|
||||
header->mkDigestIterations = LUKS_MKD_ITER;
|
||||
PBKDF2_HMAC_SHA1(mk->key,mk->keyLength,
|
||||
header->mkDigestSalt,LUKS_SALTSIZE,
|
||||
header->mkDigestIterations,
|
||||
header->mkDigest,LUKS_DIGESTSIZE);
|
||||
|
||||
currentSector = round_up_modulo(LUKS_PHDR_SIZE, alignSectors);
|
||||
for(i = 0; i < LUKS_NUMKEYS; ++i) {
|
||||
header->keyblock[i].active = LUKS_KEY_DISABLED;
|
||||
header->keyblock[i].keyMaterialOffset = currentSector;
|
||||
header->keyblock[i].stripes = stripes;
|
||||
currentSector = round_up_modulo(currentSector + blocksPerStripeSet, alignSectors);
|
||||
}
|
||||
currentSector = round_up_modulo(currentSector, alignPayload);
|
||||
|
||||
header->payloadOffset=currentSector;
|
||||
|
||||
uuid_generate(partitionUuid);
|
||||
uuid_unparse(partitionUuid, header->uuid);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int LUKS_set_key(const char *device, unsigned int keyIndex,
|
||||
const char *password, size_t passwordLen,
|
||||
struct luks_phdr *hdr, struct luks_masterkey *mk,
|
||||
struct setup_backend *backend)
|
||||
{
|
||||
char derivedKey[hdr->keyBytes];
|
||||
char *AfKey;
|
||||
unsigned int AFEKSize;
|
||||
int r;
|
||||
|
||||
if(hdr->keyblock[keyIndex].active != LUKS_KEY_DISABLED) {
|
||||
set_error( _("key %d active, purge first"), keyIndex);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if(hdr->keyblock[keyIndex].stripes < LUKS_STRIPES) {
|
||||
set_error(_("key material section %d includes too few stripes. Header manipulation?"),keyIndex);
|
||||
return -EINVAL;
|
||||
}
|
||||
r = getRandom(hdr->keyblock[keyIndex].passwordSalt, LUKS_SALTSIZE);
|
||||
if(r < 0) return r;
|
||||
|
||||
// assert((mk->keyLength % TWOFISH_BLOCKSIZE) == 0); FIXME
|
||||
|
||||
PBKDF2_HMAC_SHA1(password,passwordLen,
|
||||
hdr->keyblock[keyIndex].passwordSalt,LUKS_SALTSIZE,
|
||||
hdr->keyblock[keyIndex].passwordIterations,
|
||||
derivedKey, hdr->keyBytes);
|
||||
/*
|
||||
* AF splitting, the masterkey stored in mk->key is splitted to AfMK
|
||||
*/
|
||||
AFEKSize = hdr->keyblock[keyIndex].stripes*mk->keyLength;
|
||||
AfKey = (char *)malloc(AFEKSize);
|
||||
if(AfKey == NULL) return -ENOMEM;
|
||||
|
||||
r = AF_split(mk->key,AfKey,mk->keyLength,hdr->keyblock[keyIndex].stripes);
|
||||
if(r < 0) goto out;
|
||||
|
||||
/* Encryption via dm */
|
||||
r = LUKS_encrypt_to_storage(AfKey,
|
||||
AFEKSize,
|
||||
hdr,
|
||||
derivedKey,
|
||||
hdr->keyBytes,
|
||||
device,
|
||||
hdr->keyblock[keyIndex].keyMaterialOffset,
|
||||
backend);
|
||||
if(r < 0) {
|
||||
if(!get_error())
|
||||
set_error("Failed to write to key storage");
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Mark the key as active in phdr */
|
||||
hdr->keyblock[keyIndex].active = LUKS_KEY_ENABLED;
|
||||
r = LUKS_write_phdr(device,hdr);
|
||||
if(r < 0) goto out;
|
||||
|
||||
r = 0;
|
||||
out:
|
||||
free(AfKey);
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Try to open a particular key slot,
|
||||
|
||||
*/
|
||||
|
||||
int LUKS_open_key(const char *device,
|
||||
unsigned int keyIndex,
|
||||
const char *password,
|
||||
size_t passwordLen,
|
||||
struct luks_phdr *hdr,
|
||||
struct luks_masterkey *mk,
|
||||
struct setup_backend *backend)
|
||||
{
|
||||
char derivedKey[hdr->keyBytes];
|
||||
char *AfKey;
|
||||
size_t AFEKSize;
|
||||
char checkHashBuf[LUKS_DIGESTSIZE];
|
||||
int r;
|
||||
|
||||
if(hdr->keyblock[keyIndex].active != LUKS_KEY_ENABLED) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
// assert((mk->keyLength % TWOFISH_BLOCKSIZE) == 0); FIXME
|
||||
|
||||
AFEKSize = hdr->keyblock[keyIndex].stripes*mk->keyLength;
|
||||
AfKey = (char *)malloc(AFEKSize);
|
||||
if(AfKey == NULL) return -ENOMEM;
|
||||
|
||||
PBKDF2_HMAC_SHA1(password,passwordLen,
|
||||
hdr->keyblock[keyIndex].passwordSalt,LUKS_SALTSIZE,
|
||||
hdr->keyblock[keyIndex].passwordIterations,
|
||||
derivedKey, hdr->keyBytes);
|
||||
|
||||
r = LUKS_decrypt_from_storage(AfKey,
|
||||
AFEKSize,
|
||||
hdr,
|
||||
derivedKey,
|
||||
hdr->keyBytes,
|
||||
device,
|
||||
hdr->keyblock[keyIndex].keyMaterialOffset,
|
||||
backend);
|
||||
if(r < 0) {
|
||||
if(!get_error())
|
||||
set_error("Failed to read from key storage");
|
||||
goto out;
|
||||
}
|
||||
|
||||
r = AF_merge(AfKey,mk->key,mk->keyLength,hdr->keyblock[keyIndex].stripes);
|
||||
if(r < 0) goto out;
|
||||
|
||||
PBKDF2_HMAC_SHA1(mk->key,mk->keyLength,
|
||||
hdr->mkDigestSalt,LUKS_SALTSIZE,
|
||||
hdr->mkDigestIterations,
|
||||
checkHashBuf,LUKS_DIGESTSIZE);
|
||||
|
||||
r = (memcmp(checkHashBuf,hdr->mkDigest, LUKS_DIGESTSIZE) == 0)?0:-EPERM;
|
||||
out:
|
||||
free(AfKey);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
/* Tries to open any key from a given LUKS device reading the header on its own */
|
||||
int LUKS_open_any_key(const char *device,
|
||||
const char *password,
|
||||
size_t passwordLen,
|
||||
struct luks_phdr *hdr,
|
||||
struct luks_masterkey **mk,
|
||||
struct setup_backend *backend)
|
||||
{
|
||||
int r;
|
||||
|
||||
r = LUKS_read_phdr(device, hdr);
|
||||
if(r < 0)
|
||||
return r;
|
||||
return LUKS_open_any_key_with_hdr(device,password,passwordLen,hdr,mk,backend);
|
||||
}
|
||||
|
||||
|
||||
int LUKS_open_any_key_with_hdr(const char *device,
|
||||
const char *password,
|
||||
size_t passwordLen,
|
||||
struct luks_phdr *hdr,
|
||||
struct luks_masterkey **mk,
|
||||
struct setup_backend *backend)
|
||||
{
|
||||
unsigned int i;
|
||||
int r;
|
||||
|
||||
*mk=LUKS_alloc_masterkey(hdr->keyBytes);
|
||||
for(i=0; i<LUKS_NUMKEYS; i++) {
|
||||
r = LUKS_open_key(device, i, password, passwordLen, hdr, *mk, backend);
|
||||
if(r == 0) {
|
||||
return i;
|
||||
}
|
||||
/* Do not retry for errors that are no -EPERM or -EINVAL, former meaning password wrong, latter key slot inactive */
|
||||
if ((r != -EPERM) && (r != -EINVAL))
|
||||
return r;
|
||||
}
|
||||
/* Warning, early returns above */
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
/*
|
||||
* Wipe patterns according to Gutmann's Paper
|
||||
*/
|
||||
|
||||
static void wipeSpecial(char *buffer, size_t buffer_size, unsigned int turn)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
unsigned char write_modes[][3] = {
|
||||
{"\x55\x55\x55"}, {"\xaa\xaa\xaa"}, {"\x92\x49\x24"},
|
||||
{"\x49\x24\x92"}, {"\x24\x92\x49"}, {"\x00\x00\x00"},
|
||||
{"\x11\x11\x11"}, {"\x22\x22\x22"}, {"\x33\x33\x33"},
|
||||
{"\x44\x44\x44"}, {"\x55\x55\x55"}, {"\x66\x66\x66"},
|
||||
{"\x77\x77\x77"}, {"\x88\x88\x88"}, {"\x99\x99\x99"},
|
||||
{"\xaa\xaa\xaa"}, {"\xbb\xbb\xbb"}, {"\xcc\xcc\xcc"},
|
||||
{"\xdd\xdd\xdd"}, {"\xee\xee\xee"}, {"\xff\xff\xff"},
|
||||
{"\x92\x49\x24"}, {"\x49\x24\x92"}, {"\x24\x92\x49"},
|
||||
{"\x6d\xb6\xdb"}, {"\xb6\xdb\x6d"}, {"\xdb\x6d\xb6"}
|
||||
};
|
||||
|
||||
for(i = 0; i < buffer_size / 3; ++i) {
|
||||
memcpy(buffer, write_modes[turn], 3);
|
||||
buffer += 3;
|
||||
}
|
||||
}
|
||||
|
||||
static int wipe(const char *device, unsigned int from, unsigned int to)
|
||||
{
|
||||
int devfd;
|
||||
char *buffer;
|
||||
unsigned int i;
|
||||
unsigned int bufLen = (to - from) * SECTOR_SIZE;
|
||||
int r = 0;
|
||||
|
||||
devfd = open(device, O_RDWR | O_DIRECT | O_SYNC);
|
||||
if(devfd == -1) {
|
||||
set_error(_("Can't open device %s"), device);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
buffer = (char *) malloc(bufLen);
|
||||
if(!buffer) return -ENOMEM;
|
||||
|
||||
for(i = 0; i < 39; ++i) {
|
||||
if (i >= 0 && i < 5) getRandom(buffer, bufLen);
|
||||
else if(i >= 5 && i < 32) wipeSpecial(buffer, bufLen, i - 5);
|
||||
else if(i >= 32 && i < 38) getRandom(buffer, bufLen);
|
||||
else if(i >= 38 && i < 39) memset(buffer, 0xFF, bufLen);
|
||||
|
||||
if(write_lseek_blockwise(devfd, buffer, bufLen, from * SECTOR_SIZE) < 0) {
|
||||
r = -EIO;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
free(buffer);
|
||||
close(devfd);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int LUKS_del_key(const char *device, unsigned int keyIndex)
|
||||
{
|
||||
struct luks_phdr hdr;
|
||||
unsigned int startOffset, endOffset, stripesLen;
|
||||
int r;
|
||||
|
||||
r = LUKS_read_phdr(device, &hdr);
|
||||
if(r != 0) {
|
||||
/* placeholder */
|
||||
} else if(keyIndex >= LUKS_NUMKEYS || hdr.keyblock[keyIndex].active != LUKS_KEY_ENABLED) {
|
||||
set_error(_("Key %d not active. Can't wipe.\n"), keyIndex);
|
||||
r = -1;
|
||||
} else {
|
||||
/* secure deletion of key material */
|
||||
startOffset = hdr.keyblock[keyIndex].keyMaterialOffset;
|
||||
stripesLen = hdr.keyBytes * hdr.keyblock[keyIndex].stripes;
|
||||
endOffset = startOffset + div_round_up(stripesLen, SECTOR_SIZE);
|
||||
|
||||
r = wipe(device, startOffset, endOffset);
|
||||
if(r == 0) {
|
||||
/* mark the key as inactive in header */
|
||||
hdr.keyblock[keyIndex].active = LUKS_KEY_DISABLED;
|
||||
r = LUKS_write_phdr(device, &hdr);
|
||||
}
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int LUKS_is_last_keyslot(const char *device, unsigned int keyIndex)
|
||||
{
|
||||
struct luks_phdr hdr;
|
||||
unsigned int i;
|
||||
int r;
|
||||
|
||||
r = LUKS_read_phdr(device, &hdr);
|
||||
if(r < 0) return r;
|
||||
|
||||
for(i = 0; i < LUKS_NUMKEYS; i++) {
|
||||
if(i != keyIndex && hdr.keyblock[i].active == LUKS_KEY_ENABLED)
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int LUKS_benchmarkt_iterations()
|
||||
{
|
||||
return PBKDF2_performance_check()/2;
|
||||
}
|
||||
|
||||
int LUKS_device_ready(const char *device, int mode)
|
||||
{
|
||||
int devfd;
|
||||
struct stat st;
|
||||
|
||||
if(stat(device, &st) < 0) {
|
||||
set_error(_("Device %s doesn't exist or access denied."), device);
|
||||
return 0;
|
||||
}
|
||||
|
||||
devfd = open(device, mode | O_DIRECT | O_SYNC);
|
||||
if(devfd < 0) {
|
||||
set_error(_("Can't open device %s for %s%saccess."), device,
|
||||
(mode & O_EXCL)?_("exclusive "):"",
|
||||
(mode & O_RDWR)?_("writable "):"read-only ");
|
||||
return 0;
|
||||
}
|
||||
close(devfd);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Local Variables:
|
||||
// c-basic-offset: 8
|
||||
// indent-tabs-mode: nil
|
||||
// End:
|
||||
144
luks/luks.h
144
luks/luks.h
@@ -1,144 +0,0 @@
|
||||
#ifndef INCLUDED_CRYPTSETUP_LUKS_LUKS_H
|
||||
#define INCLUDED_CRYPTSETUP_LUKS_LUKS_H
|
||||
|
||||
/*
|
||||
* LUKS partition header
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <netinet/in.h>
|
||||
#include "libcryptsetup.h"
|
||||
#include "internal.h"
|
||||
|
||||
#define LUKS_CIPHERNAME_L 32
|
||||
#define LUKS_CIPHERMODE_L 32
|
||||
#define LUKS_HASHSPEC_L 32
|
||||
#define LUKS_DIGESTSIZE 20 // since SHA1
|
||||
#define LUKS_HMACSIZE 32
|
||||
#define LUKS_SALTSIZE 32
|
||||
#define LUKS_NUMKEYS 8
|
||||
|
||||
// Numbers of iterations for the master key digest
|
||||
#define LUKS_MKD_ITER 10
|
||||
|
||||
// LUKS_KT defines Key types
|
||||
|
||||
#define LUKS_KEY_DISABLED_OLD 0
|
||||
#define LUKS_KEY_ENABLED_OLD 0xCAFE
|
||||
|
||||
#define LUKS_KEY_DISABLED 0x0000DEAD
|
||||
#define LUKS_KEY_ENABLED 0x00AC71F3
|
||||
|
||||
#define LUKS_STRIPES 4000
|
||||
|
||||
// partition header starts with magic
|
||||
|
||||
#define LUKS_MAGIC {'L','U','K','S', 0xba, 0xbe};
|
||||
#define LUKS_MAGIC_L 6
|
||||
|
||||
#define LUKS_PHDR_SIZE (sizeof(struct luks_phdr)/SECTOR_SIZE+1)
|
||||
|
||||
/* Actually we need only 37, but we don't want struct autoaligning to kick in */
|
||||
#define UUID_STRING_L 40
|
||||
|
||||
/* We don't have gettext support in LUKS */
|
||||
|
||||
#define _(Text) Text
|
||||
|
||||
/* Any integer values are stored in network byte order on disk and must be
|
||||
converted */
|
||||
|
||||
struct luks_phdr {
|
||||
char magic[LUKS_MAGIC_L];
|
||||
uint16_t version;
|
||||
char cipherName[LUKS_CIPHERNAME_L];
|
||||
char cipherMode[LUKS_CIPHERMODE_L];
|
||||
char hashSpec[LUKS_HASHSPEC_L];
|
||||
uint32_t payloadOffset;
|
||||
uint32_t keyBytes;
|
||||
char mkDigest[LUKS_DIGESTSIZE];
|
||||
char mkDigestSalt[LUKS_SALTSIZE];
|
||||
uint32_t mkDigestIterations;
|
||||
char uuid[UUID_STRING_L];
|
||||
|
||||
struct {
|
||||
uint32_t active;
|
||||
|
||||
/* parameters used for password processing */
|
||||
uint32_t passwordIterations;
|
||||
char passwordSalt[LUKS_SALTSIZE];
|
||||
|
||||
/* parameters used for AF store/load */
|
||||
uint32_t keyMaterialOffset;
|
||||
uint32_t stripes;
|
||||
} keyblock[LUKS_NUMKEYS];
|
||||
};
|
||||
|
||||
struct luks_masterkey {
|
||||
size_t keyLength;
|
||||
char key[];
|
||||
};
|
||||
|
||||
struct luks_masterkey *LUKS_alloc_masterkey(int keylength);
|
||||
|
||||
void LUKS_dealloc_masterkey(struct luks_masterkey *mk);
|
||||
|
||||
struct luks_masterkey *LUKS_generate_masterkey(int keylength);
|
||||
|
||||
int LUKS_generate_phdr(struct luks_phdr *header,
|
||||
const struct luks_masterkey *mk, const char *cipherName,
|
||||
const char *cipherMode, unsigned int stripes,
|
||||
unsigned int alignPayload);
|
||||
|
||||
int LUKS_read_phdr(const char *device, struct luks_phdr *hdr);
|
||||
|
||||
int LUKS_write_phdr(const char *device, struct luks_phdr *hdr);
|
||||
|
||||
int LUKS_set_key(const char *device,
|
||||
unsigned int keyIndex,
|
||||
const char *password,
|
||||
size_t passwordLen,
|
||||
struct luks_phdr *hdr,
|
||||
struct luks_masterkey *mk,
|
||||
struct setup_backend *backend);
|
||||
|
||||
int LUKS_open_key(const char *device,
|
||||
unsigned int keyIndex,
|
||||
const char *password,
|
||||
size_t passwordLen,
|
||||
struct luks_phdr *hdr,
|
||||
struct luks_masterkey *mk,
|
||||
struct setup_backend *backend);
|
||||
|
||||
int LUKS_open_any_key(const char *device,
|
||||
const char *password,
|
||||
size_t passwordLen,
|
||||
struct luks_phdr *hdr,
|
||||
struct luks_masterkey **mk,
|
||||
struct setup_backend *backend);
|
||||
|
||||
int LUKS_open_any_key_with_hdr(const char *device,
|
||||
const char *password,
|
||||
size_t passwordLen,
|
||||
struct luks_phdr *hdr,
|
||||
struct luks_masterkey **mk,
|
||||
struct setup_backend *backend);
|
||||
|
||||
|
||||
int LUKS_del_key(const char *device, unsigned int keyIndex);
|
||||
int LUKS_is_last_keyslot(const char *device, unsigned int keyIndex);
|
||||
int LUKS_benchmarkt_iterations();
|
||||
|
||||
int LUKS_encrypt_to_storage(char *src, size_t srcLength,
|
||||
struct luks_phdr *hdr,
|
||||
char *key, size_t keyLength,
|
||||
const char *device,
|
||||
unsigned int sector, struct setup_backend *backend);
|
||||
|
||||
int LUKS_decrypt_from_storage(char *dst, size_t dstLength,
|
||||
struct luks_phdr *hdr,
|
||||
char *key, size_t keyLength,
|
||||
const char *device,
|
||||
unsigned int sector, struct setup_backend *backend);
|
||||
int LUKS_device_ready(const char *device, int mode);
|
||||
#endif
|
||||
114
luks/pbkdf.c
114
luks/pbkdf.c
@@ -1,114 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004 Clemens Fruhwirth <clemens@endorphin.org>
|
||||
* Implementation of PBKDF2-HMAC-SHA1 according to RFC 2898.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include "hmac_sha1.h"
|
||||
#include "XORblock.h"
|
||||
#include <assert.h>
|
||||
|
||||
static unsigned int *__PBKDF2_global_j;
|
||||
static unsigned int __PBKDF2_performance=0;
|
||||
|
||||
void PBKDF2_HMAC_SHA1(const char *password, size_t passwordLen,
|
||||
const char *salt, size_t saltLen, unsigned int iterations,
|
||||
char *dKey, size_t dKeyLen)
|
||||
{
|
||||
uint32_t i=1;
|
||||
unsigned int j;
|
||||
/* U_n is the buffer for U_n values */
|
||||
unsigned char U_n[SHA1_DIGEST_SIZE];
|
||||
/* F_buf is the XOR buffer for F function */
|
||||
char F_buf[SHA1_DIGEST_SIZE];
|
||||
hmac_ctx templateCtx;
|
||||
|
||||
/* We need a global pointer for signal handlers */
|
||||
__PBKDF2_global_j = &j;
|
||||
|
||||
/* Make a template context initialized with password as key */
|
||||
hmac_sha_begin(&templateCtx);
|
||||
hmac_sha_key((unsigned char *) password,passwordLen,&templateCtx);
|
||||
|
||||
#define HMAC_REINIT(__ctx) memcpy(&__ctx,&templateCtx,sizeof(__ctx))
|
||||
|
||||
/* The first hash iteration is done different, therefor
|
||||
we reduce iterations to conveniently use it as a loop
|
||||
counter */
|
||||
assert(iterations != 0);
|
||||
iterations--;
|
||||
|
||||
while(dKeyLen > 0) {
|
||||
hmac_ctx ctx;
|
||||
uint32_t iNetworkOrdered;
|
||||
unsigned int blocksize = dKeyLen<SHA1_DIGEST_SIZE?dKeyLen:SHA1_DIGEST_SIZE;
|
||||
|
||||
j=iterations;
|
||||
HMAC_REINIT(ctx);
|
||||
// U_1 hashing
|
||||
hmac_sha_data((unsigned char *) salt,saltLen,&ctx);
|
||||
iNetworkOrdered = htonl(i);
|
||||
hmac_sha_data((unsigned char *)&iNetworkOrdered, sizeof(uint32_t), &ctx);
|
||||
hmac_sha_end(U_n, SHA1_DIGEST_SIZE, &ctx);
|
||||
memcpy(F_buf, U_n, SHA1_DIGEST_SIZE);
|
||||
|
||||
// U_n hashing
|
||||
while(j--) {
|
||||
HMAC_REINIT(ctx);
|
||||
hmac_sha_data(U_n,SHA1_DIGEST_SIZE, &ctx);
|
||||
hmac_sha_end(U_n,SHA1_DIGEST_SIZE, &ctx);
|
||||
XORblock(F_buf,(char*) U_n,F_buf,SHA1_DIGEST_SIZE);
|
||||
}
|
||||
memcpy(dKey,F_buf,blocksize);
|
||||
dKey+=blocksize; dKeyLen-=blocksize; i++;
|
||||
}
|
||||
#undef HMAC_REINIT
|
||||
}
|
||||
|
||||
static void sigvtalarm(int foo)
|
||||
{
|
||||
__PBKDF2_performance = ~(0U) - *__PBKDF2_global_j;
|
||||
*__PBKDF2_global_j = 0;
|
||||
}
|
||||
|
||||
unsigned int PBKDF2_performance_check()
|
||||
{
|
||||
/* This code benchmarks PBKDF2 and returns
|
||||
iterations/second per SHA1_DIGEST_SIZE */
|
||||
|
||||
char buf;
|
||||
struct itimerval it;
|
||||
|
||||
if(__PBKDF2_performance != 0) return __PBKDF2_performance;
|
||||
|
||||
signal(SIGVTALRM,sigvtalarm);
|
||||
it.it_interval.tv_usec = 0;
|
||||
it.it_interval.tv_sec = 0;
|
||||
it.it_value.tv_usec = 0;
|
||||
it.it_value.tv_sec = 1;
|
||||
if (setitimer (ITIMER_VIRTUAL, &it, NULL) < 0)
|
||||
return 0;
|
||||
|
||||
PBKDF2_HMAC_SHA1("foo", 3,
|
||||
"bar", 3, ~(0U),
|
||||
&buf, 1);
|
||||
|
||||
return __PBKDF2_performance;
|
||||
}
|
||||
14
luks/pbkdf.h
14
luks/pbkdf.h
@@ -1,14 +0,0 @@
|
||||
#ifndef INCLUDED_CRYPTSETUP_LUKS_PBKDF_H
|
||||
#define INCLUDED_CRYPTSETUP_LUKS_PBKDF_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
/* */
|
||||
|
||||
void PBKDF2_HMAC_SHA1(const char *password, size_t passwordLen,
|
||||
const char *salt, size_t saltLen, unsigned int iterations,
|
||||
char *dKey, size_t dKeyLen);
|
||||
|
||||
unsigned int PBKDF2_performance_check();
|
||||
|
||||
#endif
|
||||
@@ -1,46 +0,0 @@
|
||||
/*
|
||||
* Random supply helper
|
||||
* Copyright 2004, Clemens Fruhwirth <clemens@endorphin.org>
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static int randomfd = -1;
|
||||
|
||||
int openRandom() {
|
||||
if(randomfd == -1)
|
||||
randomfd = open("/dev/urandom", O_RDONLY);
|
||||
return randomfd;
|
||||
}
|
||||
|
||||
/* This method leaks a file descriptor that can be obtained by calling
|
||||
closeRandom */
|
||||
int getRandom(char *buf, size_t len)
|
||||
{
|
||||
if(openRandom() == -1) {
|
||||
perror("getRandom:");
|
||||
return -EINVAL;
|
||||
}
|
||||
while(len) {
|
||||
int r;
|
||||
r = read(randomfd,buf,len);
|
||||
if (-1 == r && errno != -EINTR) {
|
||||
perror("read: "); return -EINVAL;
|
||||
}
|
||||
len-= r; buf += r;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void closeRandom() {
|
||||
if(randomfd != -1) {
|
||||
close(randomfd);
|
||||
randomfd = -1;
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
#ifndef INCLUDED_CRYPTSETUP_LUKS_RANDOM_H
|
||||
#define INCLUDED_CRYPTSETUP_LUKS_RANDOM_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
int getRandom(char *buf, size_t len);
|
||||
|
||||
#endif
|
||||
145
luks/sha/hmac.c
145
luks/sha/hmac.c
@@ -1,145 +0,0 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 2002, Dr Brian Gladman, Worcester, UK. All rights reserved.
|
||||
|
||||
LICENSE TERMS
|
||||
|
||||
The free distribution and use of this software in both source and binary
|
||||
form is allowed (with or without changes) provided that:
|
||||
|
||||
1. distributions of this source code include the above copyright
|
||||
notice, this list of conditions and the following disclaimer;
|
||||
|
||||
2. distributions in binary form include the above copyright
|
||||
notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other associated materials;
|
||||
|
||||
3. the copyright holder's name is not used to endorse products
|
||||
built using this software without specific written permission.
|
||||
|
||||
ALTERNATIVELY, provided that this notice is retained in full, this product
|
||||
may be distributed under the terms of the GNU General Public License (GPL),
|
||||
in which case the provisions of the GPL apply INSTEAD OF those given above.
|
||||
|
||||
DISCLAIMER
|
||||
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its properties, including, but not limited to, correctness
|
||||
and/or fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue Date: 26/08/2003
|
||||
|
||||
This is an implementation of HMAC, the FIPS standard keyed hash function
|
||||
*/
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include "hmac.h"
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/* initialise the HMAC context to zero */
|
||||
void hmac_sha_begin(hmac_ctx cx[1])
|
||||
{
|
||||
memset(cx, 0, sizeof(hmac_ctx));
|
||||
}
|
||||
|
||||
/* input the HMAC key (can be called multiple times) */
|
||||
int hmac_sha_key(const unsigned char key[], size_t key_len, hmac_ctx cx[1])
|
||||
{
|
||||
if(cx->klen == HMAC_IN_DATA) /* error if further key input */
|
||||
return HMAC_BAD_MODE; /* is attempted in data mode */
|
||||
|
||||
if(cx->klen + key_len > HASH_INPUT_SIZE) /* if the key has to be hashed */
|
||||
{
|
||||
if(cx->klen <= HASH_INPUT_SIZE) /* if the hash has not yet been */
|
||||
{ /* started, initialise it and */
|
||||
sha_begin(cx->ctx); /* hash stored key characters */
|
||||
sha_hash(cx->key, cx->klen, cx->ctx);
|
||||
}
|
||||
|
||||
sha_hash(key, key_len, cx->ctx); /* hash long key data into hash */
|
||||
}
|
||||
else /* otherwise store key data */
|
||||
memcpy(cx->key + cx->klen, key, key_len);
|
||||
|
||||
cx->klen += key_len; /* update the key length count */
|
||||
return HMAC_OK;
|
||||
}
|
||||
|
||||
/* input the HMAC data (can be called multiple times) - */
|
||||
/* note that this call terminates the key input phase */
|
||||
void hmac_sha_data(const unsigned char data[], size_t data_len, hmac_ctx cx[1])
|
||||
{ unsigned int i;
|
||||
|
||||
if(cx->klen != HMAC_IN_DATA) /* if not yet in data phase */
|
||||
{
|
||||
if(cx->klen > HASH_INPUT_SIZE) /* if key is being hashed */
|
||||
{ /* complete the hash and */
|
||||
sha_end(cx->key, cx->ctx); /* store the result as the */
|
||||
cx->klen = HASH_OUTPUT_SIZE; /* key and set new length */
|
||||
}
|
||||
|
||||
/* pad the key if necessary */
|
||||
memset(cx->key + cx->klen, 0, HASH_INPUT_SIZE - cx->klen);
|
||||
|
||||
/* xor ipad into key value */
|
||||
for(i = 0; i < (HASH_INPUT_SIZE >> 2); ++i)
|
||||
((uint32_t*)cx->key)[i] ^= 0x36363636;
|
||||
|
||||
/* and start hash operation */
|
||||
sha_begin(cx->ctx);
|
||||
sha_hash(cx->key, HASH_INPUT_SIZE, cx->ctx);
|
||||
|
||||
/* mark as now in data mode */
|
||||
cx->klen = HMAC_IN_DATA;
|
||||
}
|
||||
|
||||
/* hash the data (if any) */
|
||||
if(data_len)
|
||||
sha_hash(data, data_len, cx->ctx);
|
||||
}
|
||||
|
||||
/* compute and output the MAC value */
|
||||
void hmac_sha_end(unsigned char mac[], size_t mac_len, hmac_ctx cx[1])
|
||||
{ unsigned char dig[HASH_OUTPUT_SIZE];
|
||||
unsigned int i;
|
||||
|
||||
/* if no data has been entered perform a null data phase */
|
||||
if(cx->klen != HMAC_IN_DATA)
|
||||
hmac_sha_data((const unsigned char*)0, 0, cx);
|
||||
|
||||
sha_end(dig, cx->ctx); /* complete the inner hash */
|
||||
|
||||
/* set outer key value using opad and removing ipad */
|
||||
for(i = 0; i < (HASH_INPUT_SIZE >> 2); ++i)
|
||||
((uint32_t*)cx->key)[i] ^= 0x36363636 ^ 0x5c5c5c5c;
|
||||
|
||||
/* perform the outer hash operation */
|
||||
sha_begin(cx->ctx);
|
||||
sha_hash(cx->key, HASH_INPUT_SIZE, cx->ctx);
|
||||
sha_hash(dig, HASH_OUTPUT_SIZE, cx->ctx);
|
||||
sha_end(dig, cx->ctx);
|
||||
|
||||
/* output the hash value */
|
||||
for(i = 0; i < mac_len; ++i)
|
||||
mac[i] = dig[i];
|
||||
}
|
||||
|
||||
/* 'do it all in one go' subroutine */
|
||||
void hmac_sha(const unsigned char key[], size_t key_len,
|
||||
const unsigned char data[], size_t data_len,
|
||||
unsigned char mac[], size_t mac_len)
|
||||
{ hmac_ctx cx[1];
|
||||
|
||||
hmac_sha_begin(cx);
|
||||
hmac_sha_key(key, key_len, cx);
|
||||
hmac_sha_data(data, data_len, cx);
|
||||
hmac_sha_end(mac, mac_len, cx);
|
||||
}
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
101
luks/sha/hmac.h
101
luks/sha/hmac.h
@@ -1,101 +0,0 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 2002, Dr Brian Gladman, Worcester, UK. All rights reserved.
|
||||
|
||||
LICENSE TERMS
|
||||
|
||||
The free distribution and use of this software in both source and binary
|
||||
form is allowed (with or without changes) provided that:
|
||||
|
||||
1. distributions of this source code include the above copyright
|
||||
notice, this list of conditions and the following disclaimer;
|
||||
|
||||
2. distributions in binary form include the above copyright
|
||||
notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other associated materials;
|
||||
|
||||
3. the copyright holder's name is not used to endorse products
|
||||
built using this software without specific written permission.
|
||||
|
||||
ALTERNATIVELY, provided that this notice is retained in full, this product
|
||||
may be distributed under the terms of the GNU General Public License (GPL),
|
||||
in which case the provisions of the GPL apply INSTEAD OF those given above.
|
||||
|
||||
DISCLAIMER
|
||||
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its properties, including, but not limited to, correctness
|
||||
and/or fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue Date: 26/08/2003
|
||||
|
||||
This is an implementation of HMAC, the FIPS standard keyed hash function
|
||||
*/
|
||||
|
||||
#ifndef _HMAC_H
|
||||
#define _HMAC_H
|
||||
|
||||
#include <memory.h>
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#if !defined(USE_SHA1) && !defined(USE_SHA256)
|
||||
#error define USE_SHA1 or USE_SHA256 to set the HMAC hash algorithm
|
||||
#endif
|
||||
|
||||
#ifdef USE_SHA1
|
||||
|
||||
#include "sha1.h"
|
||||
|
||||
#define HASH_INPUT_SIZE SHA1_BLOCK_SIZE
|
||||
#define HASH_OUTPUT_SIZE SHA1_DIGEST_SIZE
|
||||
#define sha_ctx sha1_ctx
|
||||
#define sha_begin sha1_begin
|
||||
#define sha_hash sha1_hash
|
||||
#define sha_end sha1_end
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef USE_SHA256
|
||||
|
||||
#include "sha2.h"
|
||||
|
||||
#define HASH_INPUT_SIZE SHA256_BLOCK_SIZE
|
||||
#define HASH_OUTPUT_SIZE SHA256_DIGEST_SIZE
|
||||
#define sha_ctx sha256_ctx
|
||||
#define sha_begin sha256_begin
|
||||
#define sha_hash sha256_hash
|
||||
#define sha_end sha256_end
|
||||
|
||||
#endif
|
||||
|
||||
#define HMAC_OK 0
|
||||
#define HMAC_BAD_MODE -1
|
||||
#define HMAC_IN_DATA 0xffffffff
|
||||
|
||||
typedef struct
|
||||
{ unsigned char key[HASH_INPUT_SIZE];
|
||||
sha_ctx ctx[1];
|
||||
unsigned long klen;
|
||||
} hmac_ctx;
|
||||
|
||||
void hmac_sha_begin(hmac_ctx cx[1]);
|
||||
|
||||
int hmac_sha_key(const unsigned char key[], size_t key_len, hmac_ctx cx[1]);
|
||||
|
||||
void hmac_sha_data(const unsigned char data[], size_t data_len, hmac_ctx cx[1]);
|
||||
|
||||
void hmac_sha_end(unsigned char mac[], size_t mac_len, hmac_ctx cx[1]);
|
||||
|
||||
void hmac_sha(const unsigned char key[], size_t key_len,
|
||||
const unsigned char data[], size_t data_len,
|
||||
unsigned char mac[], size_t mac_len);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,2 +0,0 @@
|
||||
#define USE_SHA1
|
||||
#include "hmac.c"
|
||||
@@ -1,2 +0,0 @@
|
||||
#define USE_SHA1
|
||||
#include "hmac.h"
|
||||
355
luks/sha/sha1.c
355
luks/sha/sha1.c
@@ -1,355 +0,0 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 2002, Dr Brian Gladman, Worcester, UK. All rights reserved.
|
||||
|
||||
LICENSE TERMS
|
||||
|
||||
The free distribution and use of this software in both source and binary
|
||||
form is allowed (with or without changes) provided that:
|
||||
|
||||
1. distributions of this source code include the above copyright
|
||||
notice, this list of conditions and the following disclaimer;
|
||||
|
||||
2. distributions in binary form include the above copyright
|
||||
notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other associated materials;
|
||||
|
||||
3. the copyright holder's name is not used to endorse products
|
||||
built using this software without specific written permission.
|
||||
|
||||
ALTERNATIVELY, provided that this notice is retained in full, this product
|
||||
may be distributed under the terms of the GNU General Public License (GPL),
|
||||
in which case the provisions of the GPL apply INSTEAD OF those given above.
|
||||
|
||||
DISCLAIMER
|
||||
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its properties, including, but not limited to, correctness
|
||||
and/or fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue Date: 16/01/2004
|
||||
|
||||
This is a byte oriented version of SHA1 that operates on arrays of bytes
|
||||
stored in memory. It runs at 22 cycles per byte on a Pentium P4 processor
|
||||
*/
|
||||
|
||||
#include <string.h> /* for memcpy() etc. */
|
||||
#include <stdlib.h> /* for _lrotl with VC++ */
|
||||
|
||||
#include "sha1.h"
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/*
|
||||
To obtain the highest speed on processors with 32-bit words, this code
|
||||
needs to determine the order in which bytes are packed into such words.
|
||||
The following block of code is an attempt to capture the most obvious
|
||||
ways in which various environemnts specify their endian definitions.
|
||||
It may well fail, in which case the definitions will need to be set by
|
||||
editing at the points marked **** EDIT HERE IF NECESSARY **** below.
|
||||
*/
|
||||
|
||||
/* PLATFORM SPECIFIC INCLUDES */
|
||||
|
||||
#define BRG_LITTLE_ENDIAN 1234 /* byte 0 is least significant (i386) */
|
||||
#define BRG_BIG_ENDIAN 4321 /* byte 0 is most significant (mc68k) */
|
||||
|
||||
#if defined(__GNUC__) || defined(__GNU_LIBRARY__)
|
||||
# if defined(__FreeBSD__) || defined(__OpenBSD__)
|
||||
# include <sys/endian.h>
|
||||
# elif defined( BSD ) && ( BSD >= 199103 )
|
||||
# include <machine/endian.h>
|
||||
# elif defined(__APPLE__)
|
||||
# if defined(__BIG_ENDIAN__) && !defined( BIG_ENDIAN )
|
||||
# define BIG_ENDIAN
|
||||
# elif defined(__LITTLE_ENDIAN__) && !defined( LITTLE_ENDIAN )
|
||||
# define LITTLE_ENDIAN
|
||||
# endif
|
||||
# else
|
||||
# include <endian.h>
|
||||
# if !defined(__BEOS__)
|
||||
# include <byteswap.h>
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !defined(PLATFORM_BYTE_ORDER)
|
||||
# if defined(LITTLE_ENDIAN) || defined(BIG_ENDIAN)
|
||||
# if defined(LITTLE_ENDIAN) && !defined(BIG_ENDIAN)
|
||||
# define PLATFORM_BYTE_ORDER BRG_LITTLE_ENDIAN
|
||||
# elif !defined(LITTLE_ENDIAN) && defined(BIG_ENDIAN)
|
||||
# define PLATFORM_BYTE_ORDER BRG_BIG_ENDIAN
|
||||
# elif defined(BYTE_ORDER) && (BYTE_ORDER == LITTLE_ENDIAN)
|
||||
# define PLATFORM_BYTE_ORDER BRG_LITTLE_ENDIAN
|
||||
# elif defined(BYTE_ORDER) && (BYTE_ORDER == BIG_ENDIAN)
|
||||
# define PLATFORM_BYTE_ORDER BRG_BIG_ENDIAN
|
||||
# endif
|
||||
# elif defined(_LITTLE_ENDIAN) || defined(_BIG_ENDIAN)
|
||||
# if defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN)
|
||||
# define PLATFORM_BYTE_ORDER BRG_LITTLE_ENDIAN
|
||||
# elif !defined(_LITTLE_ENDIAN) && defined(_BIG_ENDIAN)
|
||||
# define PLATFORM_BYTE_ORDER BRG_BIG_ENDIAN
|
||||
# elif defined(_BYTE_ORDER) && (_BYTE_ORDER == _LITTLE_ENDIAN)
|
||||
# define PLATFORM_BYTE_ORDER BRG_LITTLE_ENDIAN
|
||||
# elif defined(_BYTE_ORDER) && (_BYTE_ORDER == _BIG_ENDIAN)
|
||||
# define PLATFORM_BYTE_ORDER BRG_BIG_ENDIAN
|
||||
# endif
|
||||
# elif defined(__LITTLE_ENDIAN__) || defined(__BIG_ENDIAN__)
|
||||
# if defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__)
|
||||
# define PLATFORM_BYTE_ORDER BRG_LITTLE_ENDIAN
|
||||
# elif !defined(__LITTLE_ENDIAN__) && defined(__BIG_ENDIAN__)
|
||||
# define PLATFORM_BYTE_ORDER BRG_BIG_ENDIAN
|
||||
# elif defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __LITTLE_ENDIAN__)
|
||||
# define PLATFORM_BYTE_ORDER BRG_LITTLE_ENDIAN
|
||||
# elif defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __BIG_ENDIAN__)
|
||||
# define PLATFORM_BYTE_ORDER BRG_BIG_ENDIAN
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* if the platform is still unknown, try to find its byte order */
|
||||
/* from commonly used machine defines */
|
||||
|
||||
#if !defined(PLATFORM_BYTE_ORDER)
|
||||
|
||||
#if defined( __alpha__ ) || defined( __alpha ) || defined( i386 ) || \
|
||||
defined( __i386__ ) || defined( _M_I86 ) || defined( _M_IX86 ) || \
|
||||
defined( __OS2__ ) || defined( sun386 ) || defined( __TURBOC__ ) || \
|
||||
defined( vax ) || defined( vms ) || defined( VMS ) || \
|
||||
defined( __VMS )
|
||||
# define PLATFORM_BYTE_ORDER BRG_LITTLE_ENDIAN
|
||||
|
||||
#elif defined( AMIGA ) || defined( applec ) || defined( __AS400__ ) || \
|
||||
defined( _CRAY ) || defined( __hppa ) || defined( __hp9000 ) || \
|
||||
defined( ibm370 ) || defined( mc68000 ) || defined( m68k ) || \
|
||||
defined( __MRC__ ) || defined( __MVS__ ) || defined( __MWERKS__ ) || \
|
||||
defined( sparc ) || defined( __sparc) || defined( SYMANTEC_C ) || \
|
||||
defined( __TANDEM ) || defined( THINK_C ) || defined( __VMCMS__ )
|
||||
# define PLATFORM_BYTE_ORDER BRG_BIG_ENDIAN
|
||||
|
||||
#elif 0 /* **** EDIT HERE IF NECESSARY **** */
|
||||
# define PLATFORM_BYTE_ORDER BRG_LITTLE_ENDIAN
|
||||
#elif 0 /* **** EDIT HERE IF NECESSARY **** */
|
||||
# define PLATFORM_BYTE_ORDER BRG_BIG_ENDIAN
|
||||
#else
|
||||
# error Please edit sha1.c (line 134 or 136) to set the platform byte order
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma intrinsic(memcpy)
|
||||
#endif
|
||||
|
||||
#if 0 && defined(_MSC_VER)
|
||||
#define rotl32 _lrotl
|
||||
#define rotr32 _lrotr
|
||||
#else
|
||||
#define rotl32(x,n) (((x) << n) | ((x) >> (32 - n)))
|
||||
#define rotr32(x,n) (((x) >> n) | ((x) << (32 - n)))
|
||||
#endif
|
||||
|
||||
#if !defined(bswap_32)
|
||||
#define bswap_32(x) (rotr32((x), 24) & 0x00ff00ff | rotr32((x), 8) & 0xff00ff00)
|
||||
#endif
|
||||
|
||||
#if (PLATFORM_BYTE_ORDER == BRG_LITTLE_ENDIAN)
|
||||
#define SWAP_BYTES
|
||||
#else
|
||||
#undef SWAP_BYTES
|
||||
#endif
|
||||
|
||||
#if defined(SWAP_BYTES)
|
||||
#define bsw_32(p,n) \
|
||||
{ int _i = (n); while(_i--) ((sha1_32t*)p)[_i] = bswap_32(((sha1_32t*)p)[_i]); }
|
||||
#else
|
||||
#define bsw_32(p,n)
|
||||
#endif
|
||||
|
||||
#define SHA1_MASK (SHA1_BLOCK_SIZE - 1)
|
||||
|
||||
#if 0
|
||||
|
||||
#define ch(x,y,z) (((x) & (y)) ^ (~(x) & (z)))
|
||||
#define parity(x,y,z) ((x) ^ (y) ^ (z))
|
||||
#define maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
|
||||
|
||||
#else /* Discovered by Rich Schroeppel and Colin Plumb */
|
||||
|
||||
#define ch(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
|
||||
#define parity(x,y,z) ((x) ^ (y) ^ (z))
|
||||
#define maj(x,y,z) (((x) & (y)) | ((z) & ((x) ^ (y))))
|
||||
|
||||
#endif
|
||||
|
||||
/* Compile 64 bytes of hash data into SHA1 context. Note */
|
||||
/* that this routine assumes that the byte order in the */
|
||||
/* ctx->wbuf[] at this point is in such an order that low */
|
||||
/* address bytes in the ORIGINAL byte stream in this buffer */
|
||||
/* will go to the high end of 32-bit words on BOTH big and */
|
||||
/* little endian systems */
|
||||
|
||||
#ifdef ARRAY
|
||||
#define q(v,n) v[n]
|
||||
#else
|
||||
#define q(v,n) v##n
|
||||
#endif
|
||||
|
||||
#define one_cycle(v,a,b,c,d,e,f,k,h) \
|
||||
q(v,e) += rotr32(q(v,a),27) + \
|
||||
f(q(v,b),q(v,c),q(v,d)) + k + h; \
|
||||
q(v,b) = rotr32(q(v,b), 2)
|
||||
|
||||
#define five_cycle(v,f,k,i) \
|
||||
one_cycle(v, 0,1,2,3,4, f,k,hf(i )); \
|
||||
one_cycle(v, 4,0,1,2,3, f,k,hf(i+1)); \
|
||||
one_cycle(v, 3,4,0,1,2, f,k,hf(i+2)); \
|
||||
one_cycle(v, 2,3,4,0,1, f,k,hf(i+3)); \
|
||||
one_cycle(v, 1,2,3,4,0, f,k,hf(i+4))
|
||||
|
||||
void sha1_compile(sha1_ctx ctx[1])
|
||||
{ sha1_32t *w = ctx->wbuf;
|
||||
|
||||
#ifdef ARRAY
|
||||
sha1_32t v[5];
|
||||
memcpy(v, ctx->hash, 5 * sizeof(sha1_32t));
|
||||
#else
|
||||
sha1_32t v0, v1, v2, v3, v4;
|
||||
v0 = ctx->hash[0]; v1 = ctx->hash[1];
|
||||
v2 = ctx->hash[2]; v3 = ctx->hash[3];
|
||||
v4 = ctx->hash[4];
|
||||
#endif
|
||||
|
||||
#define hf(i) w[i]
|
||||
|
||||
five_cycle(v, ch, 0x5a827999, 0);
|
||||
five_cycle(v, ch, 0x5a827999, 5);
|
||||
five_cycle(v, ch, 0x5a827999, 10);
|
||||
one_cycle(v,0,1,2,3,4, ch, 0x5a827999, hf(15)); \
|
||||
|
||||
#undef hf
|
||||
#define hf(i) (w[(i) & 15] = rotl32( \
|
||||
w[((i) + 13) & 15] ^ w[((i) + 8) & 15] \
|
||||
^ w[((i) + 2) & 15] ^ w[(i) & 15], 1))
|
||||
|
||||
one_cycle(v,4,0,1,2,3, ch, 0x5a827999, hf(16));
|
||||
one_cycle(v,3,4,0,1,2, ch, 0x5a827999, hf(17));
|
||||
one_cycle(v,2,3,4,0,1, ch, 0x5a827999, hf(18));
|
||||
one_cycle(v,1,2,3,4,0, ch, 0x5a827999, hf(19));
|
||||
|
||||
five_cycle(v, parity, 0x6ed9eba1, 20);
|
||||
five_cycle(v, parity, 0x6ed9eba1, 25);
|
||||
five_cycle(v, parity, 0x6ed9eba1, 30);
|
||||
five_cycle(v, parity, 0x6ed9eba1, 35);
|
||||
|
||||
five_cycle(v, maj, 0x8f1bbcdc, 40);
|
||||
five_cycle(v, maj, 0x8f1bbcdc, 45);
|
||||
five_cycle(v, maj, 0x8f1bbcdc, 50);
|
||||
five_cycle(v, maj, 0x8f1bbcdc, 55);
|
||||
|
||||
five_cycle(v, parity, 0xca62c1d6, 60);
|
||||
five_cycle(v, parity, 0xca62c1d6, 65);
|
||||
five_cycle(v, parity, 0xca62c1d6, 70);
|
||||
five_cycle(v, parity, 0xca62c1d6, 75);
|
||||
|
||||
#ifdef ARRAY
|
||||
ctx->hash[0] += v[0]; ctx->hash[1] += v[1];
|
||||
ctx->hash[2] += v[2]; ctx->hash[3] += v[3];
|
||||
ctx->hash[4] += v[4];
|
||||
#else
|
||||
ctx->hash[0] += v0; ctx->hash[1] += v1;
|
||||
ctx->hash[2] += v2; ctx->hash[3] += v3;
|
||||
ctx->hash[4] += v4;
|
||||
#endif
|
||||
}
|
||||
|
||||
void sha1_begin(sha1_ctx ctx[1])
|
||||
{
|
||||
ctx->count[0] = ctx->count[1] = 0;
|
||||
ctx->hash[0] = 0x67452301;
|
||||
ctx->hash[1] = 0xefcdab89;
|
||||
ctx->hash[2] = 0x98badcfe;
|
||||
ctx->hash[3] = 0x10325476;
|
||||
ctx->hash[4] = 0xc3d2e1f0;
|
||||
}
|
||||
|
||||
/* SHA1 hash data in an array of bytes into hash buffer and */
|
||||
/* call the hash_compile function as required. */
|
||||
|
||||
void sha1_hash(const unsigned char data[], size_t len, sha1_ctx ctx[1])
|
||||
{ sha1_32t pos = (sha1_32t)(ctx->count[0] & SHA1_MASK),
|
||||
space = SHA1_BLOCK_SIZE - pos;
|
||||
const unsigned char *sp = data;
|
||||
|
||||
if((ctx->count[0] += len) < len)
|
||||
++(ctx->count[1]);
|
||||
|
||||
while(len >= space) /* tranfer whole blocks if possible */
|
||||
{
|
||||
memcpy(((unsigned char*)ctx->wbuf) + pos, sp, space);
|
||||
sp += space; len -= space; space = SHA1_BLOCK_SIZE; pos = 0;
|
||||
bsw_32(ctx->wbuf, SHA1_BLOCK_SIZE >> 2);
|
||||
sha1_compile(ctx);
|
||||
}
|
||||
|
||||
memcpy(((unsigned char*)ctx->wbuf) + pos, sp, len);
|
||||
}
|
||||
|
||||
/* SHA1 final padding and digest calculation */
|
||||
|
||||
void sha1_end(unsigned char hval[], sha1_ctx ctx[1])
|
||||
{ sha1_32t i = (sha1_32t)(ctx->count[0] & SHA1_MASK);
|
||||
|
||||
/* put bytes in the buffer in an order in which references to */
|
||||
/* 32-bit words will put bytes with lower addresses into the */
|
||||
/* top of 32 bit words on BOTH big and little endian machines */
|
||||
bsw_32(ctx->wbuf, (i + 3) >> 2);
|
||||
|
||||
/* we now need to mask valid bytes and add the padding which is */
|
||||
/* a single 1 bit and as many zero bits as necessary. Note that */
|
||||
/* we can always add the first padding byte here because the */
|
||||
/* buffer always has at least one empty slot */
|
||||
ctx->wbuf[i >> 2] &= 0xffffff80 << 8 * (~i & 3);
|
||||
ctx->wbuf[i >> 2] |= 0x00000080 << 8 * (~i & 3);
|
||||
|
||||
/* we need 9 or more empty positions, one for the padding byte */
|
||||
/* (above) and eight for the length count. If there is not */
|
||||
/* enough space, pad and empty the buffer */
|
||||
if(i > SHA1_BLOCK_SIZE - 9)
|
||||
{
|
||||
if(i < 60) ctx->wbuf[15] = 0;
|
||||
sha1_compile(ctx);
|
||||
i = 0;
|
||||
}
|
||||
else /* compute a word index for the empty buffer positions */
|
||||
i = (i >> 2) + 1;
|
||||
|
||||
while(i < 14) /* and zero pad all but last two positions */
|
||||
ctx->wbuf[i++] = 0;
|
||||
|
||||
/* the following 32-bit length fields are assembled in the */
|
||||
/* wrong byte order on little endian machines but this is */
|
||||
/* corrected later since they are only ever used as 32-bit */
|
||||
/* word values. */
|
||||
ctx->wbuf[14] = (ctx->count[1] << 3) | (ctx->count[0] >> 29);
|
||||
ctx->wbuf[15] = ctx->count[0] << 3;
|
||||
sha1_compile(ctx);
|
||||
|
||||
/* extract the hash value as bytes in case the hash buffer is */
|
||||
/* misaligned for 32-bit words */
|
||||
for(i = 0; i < SHA1_DIGEST_SIZE; ++i)
|
||||
hval[i] = (unsigned char)(ctx->hash[i >> 2] >> (8 * (~i & 3)));
|
||||
}
|
||||
|
||||
void sha1(unsigned char hval[], const unsigned char data[], size_t len)
|
||||
{ sha1_ctx cx[1];
|
||||
|
||||
sha1_begin(cx); sha1_hash(data, len, cx); sha1_end(hval, cx);
|
||||
}
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
@@ -1,85 +0,0 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 2002, Dr Brian Gladman, Worcester, UK. All rights reserved.
|
||||
|
||||
LICENSE TERMS
|
||||
|
||||
The free distribution and use of this software in both source and binary
|
||||
form is allowed (with or without changes) provided that:
|
||||
|
||||
1. distributions of this source code include the above copyright
|
||||
notice, this list of conditions and the following disclaimer;
|
||||
|
||||
2. distributions in binary form include the above copyright
|
||||
notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other associated materials;
|
||||
|
||||
3. the copyright holder's name is not used to endorse products
|
||||
built using this software without specific written permission.
|
||||
|
||||
ALTERNATIVELY, provided that this notice is retained in full, this product
|
||||
may be distributed under the terms of the GNU General Public License (GPL),
|
||||
in which case the provisions of the GPL apply INSTEAD OF those given above.
|
||||
|
||||
DISCLAIMER
|
||||
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its properties, including, but not limited to, correctness
|
||||
and/or fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue Date: 26/08/2003
|
||||
*/
|
||||
|
||||
#ifndef _SHA1_H
|
||||
#define _SHA1_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <limits.h>
|
||||
|
||||
#define SHA1_BLOCK_SIZE 64
|
||||
#define SHA1_DIGEST_SIZE 20
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/* define an unsigned 32-bit type */
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
typedef unsigned long sha1_32t;
|
||||
#elif defined(ULONG_MAX) && ULONG_MAX == 0xfffffffful
|
||||
typedef unsigned long sha1_32t;
|
||||
#elif defined(UINT_MAX) && UINT_MAX == 0xffffffff
|
||||
typedef unsigned int sha1_32t;
|
||||
#else
|
||||
# error Please define sha1_32t as an unsigned 32 bit type in sha1.h
|
||||
#endif
|
||||
|
||||
/* type to hold the SHA256 context */
|
||||
|
||||
typedef struct
|
||||
{ sha1_32t count[2];
|
||||
sha1_32t hash[5];
|
||||
sha1_32t wbuf[16];
|
||||
} sha1_ctx;
|
||||
|
||||
/* Note that these prototypes are the same for both bit and */
|
||||
/* byte oriented implementations. However the length fields */
|
||||
/* are in bytes or bits as appropriate for the version used */
|
||||
/* and bit sequences are input as arrays of bytes in which */
|
||||
/* bit sequences run from the most to the least significant */
|
||||
/* end of each byte */
|
||||
|
||||
void sha1_compile(sha1_ctx ctx[1]);
|
||||
|
||||
void sha1_begin(sha1_ctx ctx[1]);
|
||||
void sha1_hash(const unsigned char data[], size_t len, sha1_ctx ctx[1]);
|
||||
void sha1_end(unsigned char hval[], sha1_ctx ctx[1]);
|
||||
void sha1(unsigned char hval[], const unsigned char data[], size_t len);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,129 +0,0 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
#
|
||||
# Usage: fileDiffer <afile> <bfile> <list of disk changes>
|
||||
#
|
||||
|
||||
# LUKS
|
||||
# quick regression test suite
|
||||
# Tests LUKS images for changes at certain disk offsets
|
||||
#
|
||||
# Does fast python code has to look ugly or is it just me?
|
||||
|
||||
import sys
|
||||
|
||||
class changes:
|
||||
pass
|
||||
|
||||
def parseArgs(args):
|
||||
aFileName = args[1]
|
||||
bFileName = args[2]
|
||||
changelist = []
|
||||
args[0:3] = []
|
||||
for i in args:
|
||||
mychanges = changes();
|
||||
if i.startswith('A'):
|
||||
mychanges.mode = 'ALLOWED'
|
||||
if i.startswith('R'):
|
||||
mychanges.mode = 'REQUIRED'
|
||||
mychanges.strictness = 'RANDOM'
|
||||
if i.startswith('S'):
|
||||
mychanges.mode = 'REQUIRED'
|
||||
mychanges.strictness = 'SEMANTIC'
|
||||
|
||||
dashIndex = i.find('-')
|
||||
if dashIndex == -1:
|
||||
mychanges.starts = int(i[1:])
|
||||
mychanges.ends = mychanges.starts
|
||||
else:
|
||||
mychanges.starts = int(i[1:dashIndex])
|
||||
mychanges.ends = int(i[dashIndex+1:])
|
||||
mychanges.miss = 0
|
||||
changelist.append(mychanges)
|
||||
mychanges = changes();
|
||||
mychanges.starts = 0
|
||||
# mychanges.ends will be fixed later
|
||||
mychanges.mode = 'FORBIDDEN'
|
||||
changelist.append(mychanges)
|
||||
return [aFileName, bFileName, changelist]
|
||||
|
||||
def mode(i):
|
||||
for c in changelist:
|
||||
if i >= c.starts and i<=c.ends:
|
||||
return c
|
||||
def cleanchanges(i):
|
||||
newchangelist=[]
|
||||
for c in changelist:
|
||||
if i <= c.starts or i <= c.ends:
|
||||
newchangelist.append(c)
|
||||
return newchangelist
|
||||
|
||||
[aFileName, bFileName, changelist] = parseArgs(sys.argv)
|
||||
|
||||
aFile = open(aFileName,'r')
|
||||
bFile = open(bFileName,'r')
|
||||
|
||||
aString = aFile.read()
|
||||
bString = bFile.read()
|
||||
|
||||
if len(aString) != len(bString):
|
||||
sys.exit("Mismatch different file sizes")
|
||||
|
||||
fileLen = len(aString)
|
||||
fileLen10th = fileLen/10
|
||||
|
||||
# Create a catch all entry
|
||||
changelist[-1].ends = fileLen
|
||||
|
||||
print "Changes list: (FORBIDDEN default)"
|
||||
print "start\tend\tmode\t\tstrictness"
|
||||
for i in changelist:
|
||||
if i.mode == 'REQUIRED':
|
||||
print "%d\t%d\t%s\t%s" % (i.starts, i.ends, i.mode, i.strictness)
|
||||
else:
|
||||
print "%d\t%d\t%s" % (i.starts, i.ends, i.mode)
|
||||
|
||||
|
||||
filepos = 0
|
||||
fileLen10thC = 0
|
||||
print "[..........]"
|
||||
sys.stdout.write("[")
|
||||
sys.stdout.flush()
|
||||
|
||||
modeNotTrivial = 1
|
||||
while filepos < fileLen:
|
||||
|
||||
if modeNotTrivial == 1:
|
||||
c = mode(filepos)
|
||||
# print (filepos, c.mode)
|
||||
if c.mode == 'REQUIRED':
|
||||
if aString[filepos] == bString[filepos]:
|
||||
c.miss = c.miss + 1
|
||||
else:
|
||||
if aString[filepos] != bString[filepos] and c.mode != 'ALLOWED':
|
||||
sys.exit("Mismatch at %d: change forbidden" % filepos)
|
||||
|
||||
# Do some maintaince, print progress bar, and clean changelist
|
||||
#
|
||||
# Maintaining two counters appears to be faster than modulo operation
|
||||
if fileLen10thC == fileLen10th:
|
||||
fileLen10thC = 0
|
||||
sys.stdout.write(".")
|
||||
sys.stdout.flush()
|
||||
changelist = cleanchanges(filepos)
|
||||
if len(changelist) == 1:
|
||||
modeNotTrivial = 0
|
||||
filepos = filepos + 1
|
||||
fileLen10thC = fileLen10thC + 1
|
||||
|
||||
for c in changelist:
|
||||
if c.mode == 'REQUIRED':
|
||||
if c.strictness == 'SEMANTIC' and c.miss == (c.ends-c.starts+1):
|
||||
sys.exit("Mismatch: not even a single change in region %d-%d." % (c.starts, c.ends))
|
||||
# This is not correct. We should do a statistical test
|
||||
# of the sampled data against the hypothetical distribution
|
||||
# of collision. Chi-Square Test.
|
||||
if c.strictness == 'RANDOM' and c.miss == (c.ends-c.starts+1):
|
||||
sys.exit("Mismatch: not even a single change in region %d-%d." % (c.starts, c.ends))
|
||||
|
||||
print ".] - everything ok"
|
||||
@@ -1,3 +1,11 @@
|
||||
man8_MANS = cryptsetup.8
|
||||
|
||||
EXTRA_DIST = cryptsetup.8
|
||||
if VERITYSETUP
|
||||
man8_MANS += veritysetup.8
|
||||
endif
|
||||
|
||||
if REENCRYPT
|
||||
man8_MANS += cryptsetup-reencrypt.8
|
||||
endif
|
||||
|
||||
EXTRA_DIST = cryptsetup.8 veritysetup.8 cryptsetup-reencrypt.8
|
||||
|
||||
210
man/cryptsetup-reencrypt.8
Normal file
210
man/cryptsetup-reencrypt.8
Normal file
@@ -0,0 +1,210 @@
|
||||
.TH CRYPTSETUP-REENCRYPT "8" "June 2012" "cryptsetup-reencrypt" "Maintenance Commands"
|
||||
.SH NAME
|
||||
cryptsetup-reencrypt - tool for offline LUKS device re-encryption
|
||||
.SH SYNOPSIS
|
||||
.B cryptsetup-reencrypt <options> <device>
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
Cryptsetup-reencrypt can be used to change reencryption parameters
|
||||
which otherwise require full on-disk data change (re-encryption).
|
||||
|
||||
You can regenerate \fBvolume key\fR (the real key used in on-disk encryption
|
||||
unclocked by passphrase), \fBcipher\fR, \fBcipher mode\fR.
|
||||
|
||||
Cryptsetup-reencrypt reencrypts data on LUKS device in-place. During
|
||||
reencryption process the LUKS device is marked unavailable.
|
||||
|
||||
\fIWARNING\fR: The cryptsetup-reencrypt program is not resistant to hardware
|
||||
or kernel failures during reencryption (you can lose you data in this case).
|
||||
|
||||
\fIALWAYS BE SURE YOU HAVE RELIABLE BACKUP BEFORE USING THIS TOOL.\fR
|
||||
.br
|
||||
\fITHIS TOOL IS EXPERIMENTAL.\fR
|
||||
|
||||
The reencryption can be temporarily suspended (by TERM signal or by
|
||||
using ctrl+c) but you need to retain temporary files named LUKS-<uuid>.[log|org|new].
|
||||
LUKS device is unavailable until reencryption is finished though.
|
||||
|
||||
Current working directory must by writable and temporary
|
||||
files created during reencryption must be present.
|
||||
|
||||
For more info about LUKS see cryptsetup(8).
|
||||
.PP
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
To start (or continue) re-encryption for <device> use:
|
||||
.PP
|
||||
\fIcryptsetup-reencrypt\fR <device>
|
||||
|
||||
\fB<options>\fR can be [\-\-block-size, \-\-cipher, \-\-hash, \-\-iter-time,
|
||||
\-\-use-random | \-\-use-urandom, \-\-key-file, \-\-key-slot, \-\-keyfile-offset,
|
||||
\-\-keyfile-size, \-\-tries, \-\-use-directio, \-\-use-fsync, \-\-write-log]
|
||||
|
||||
For detailed description of encryption and key file options see \fIcryptsetup(8)\fR
|
||||
man page.
|
||||
.TP
|
||||
.B "\-\-verbose, \-v"
|
||||
Print more information on command execution.
|
||||
.TP
|
||||
.B "\-\-debug"
|
||||
Run in debug mode with full diagnostic logs. Debug output
|
||||
lines are always prefixed by '#'.
|
||||
.TP
|
||||
.B "\-\-cipher, \-c" \fI<cipher-spec>\fR
|
||||
Set the cipher specification string.
|
||||
.TP
|
||||
.B "\-\-key-size, \-s \fI<bits>\fR"
|
||||
Set key size in bits. The argument has to be a multiple of 8.
|
||||
|
||||
The possible key-sizes are limited by the cipher and mode used.
|
||||
|
||||
If you are increasing key size, there must be enough space in the LUKS header
|
||||
for enlarged keyslots (data offset must be large enough) or reencryption
|
||||
cannot be performed.
|
||||
|
||||
If there is not enough space for keyslots with new key size,
|
||||
you can destructively shrink device with \-\-reduce-device-size option.
|
||||
.TP
|
||||
.B "\-\-hash, \-h \fI<hash-spec>\fR"
|
||||
Specifies the hash used in the LUKS key setup scheme and volume key digest.
|
||||
.TP
|
||||
.B "\-\-iter-time, \-i \fI<milliseconds>\fR"
|
||||
The number of milliseconds to spend with PBKDF2 passphrase processing for the
|
||||
new LUKS header.
|
||||
.TP
|
||||
.B "\-\-use-random"
|
||||
.TP
|
||||
.B "\-\-use-urandom"
|
||||
Define which kernel random number generator will be used to create the volume key.
|
||||
.TP
|
||||
.B "\-\-key-file, \-d \fIname\fR"
|
||||
Read the passphrase from file.
|
||||
|
||||
WARNING: \-\-key-file option can be used only if there only one active keyslot,
|
||||
or alternatively, also if \-\-key-slot option is specified (then all other keyslots
|
||||
will be disabled in new LUKS device).
|
||||
|
||||
If this option is not used, cryptsetup-reencrypt will ask for all active keyslot
|
||||
passphrases.
|
||||
.TP
|
||||
.B "\-\-key-slot, \-S <0-7>"
|
||||
Specify which key slot is used.
|
||||
|
||||
WARNING: All other keyslots will be disabled if this option is used.
|
||||
.TP
|
||||
.B "\-\-keyfile-offset \fIvalue\fR"
|
||||
Skip \fIvalue\fR bytes at the beginning of the key file.
|
||||
.TP
|
||||
.B "\-\-keyfile-size, \-l"
|
||||
Read a maximum of \fIvalue\fR bytes from the key file.
|
||||
Default is to read the whole file up to the compiled-in
|
||||
maximum.
|
||||
.TP
|
||||
.B "\-\-tries, \-T"
|
||||
Number of retries for invalid passphrase entry.
|
||||
.TP
|
||||
.B "\-\-block-size, \-B \fIvalue\fR"
|
||||
Use re-encryption block size of <value> in MiB.
|
||||
|
||||
Values can be between 1 and 64 MiB.
|
||||
.TP
|
||||
.B "\-\-device-size \fIsize[units]\fR"
|
||||
Instead of real device size, use specified value.
|
||||
|
||||
It means that only specified area (from the start of the device
|
||||
to the specified size) will be reencrypted.
|
||||
|
||||
WARNING: This is destructive operation.
|
||||
|
||||
If no unit suffix is specified, the size is in bytes.
|
||||
|
||||
Unit suffix can be S for 512 byte sectors, K/M/G/T (or KiB,MiB,GiB,TiB)
|
||||
for units with 1024 base or KB/MB/GB/TB for 1000 base (SI scale).
|
||||
|
||||
WARNING: This is destructive operation.
|
||||
.TP
|
||||
.B "\-\-reduce-device-size \fIsize[units]\fR"
|
||||
Enlarge data offset to specified value by shrinking device size.
|
||||
|
||||
This means that last sectors on the original device will be lost,
|
||||
ciphertext data will be effectively shifted by specified
|
||||
number of sectors.
|
||||
|
||||
It can be usefull if you e.g. added some space to underlying
|
||||
partition (so last sectors contains no data).
|
||||
|
||||
For units suffix see \-\-device-size parameter description.
|
||||
|
||||
WARNING: This is destructive operation and cannot be reverted.
|
||||
Use with extreme care - shrinked filesystems are usually unrecoverable.
|
||||
|
||||
You cannot shrink device more than by 64 MiB (131072 sectors).
|
||||
.TP
|
||||
.B "\-\-new, N"
|
||||
Create new header (encrypt not yet encrypted device).
|
||||
|
||||
This option must be used together with \-\-reduce-device-size.
|
||||
|
||||
WARNING: This is destructive operation and cannot be reverted.
|
||||
|
||||
.TP
|
||||
.B "\-\-use-directio"
|
||||
Use direct-io (O_DIRECT) for all read/write data operations.
|
||||
|
||||
Usefull if direct-io operations perform better than normal buffered
|
||||
operations (e.g. in virtual environments).
|
||||
.TP
|
||||
.B "\-\-use-fsync"
|
||||
Use fsync call after every written block.
|
||||
.TP
|
||||
.B "\-\-write-log"
|
||||
Update log file after every block write. This can slow down reencryption
|
||||
but will minimize data loss in the case of system crash.
|
||||
.TP
|
||||
.B "\-\-batch-mode, \-q"
|
||||
Suppresses all warnings and reencryption progress output.
|
||||
.TP
|
||||
.B "\-\-version"
|
||||
Show the program version.
|
||||
.SH RETURN CODES
|
||||
Cryptsetup-reencrypt returns 0 on success and a non-zero value on error.
|
||||
|
||||
Error codes are: 1 wrong parameters, 2 no permission,
|
||||
3 out of memory, 4 wrong device specified, 5 device already exists
|
||||
or device is busy.
|
||||
.SH EXAMPLES
|
||||
.TP
|
||||
Reencrypt /dev/sdb1 (change volume key)
|
||||
cryptsetup-reencrypt /dev/sdb1
|
||||
.TP
|
||||
Reencrypt and also change cipher and cipher mode
|
||||
cryptsetup-reencrypt /dev/sdb1 -c aes-xts-plain64
|
||||
.TP
|
||||
Add LUKS encryption to not yet encrypted device
|
||||
|
||||
First, be sure you have space added to disk.
|
||||
Or alternatively shrink filesystem in advance.
|
||||
.br
|
||||
Here we need 4096 512-bytes sectors (enough for 2x128 bit key).
|
||||
|
||||
fdisk -u /dev/sdb # move sdb1 partition end + 4096 sectors
|
||||
|
||||
cryptsetup-reencrypt /dev/sdb1 --new --reduce-device-size 4096
|
||||
|
||||
.SH REPORTING BUGS
|
||||
Report bugs, including ones in the documentation, on
|
||||
the cryptsetup mailing list at <dm-crypt@saout.de>
|
||||
or in the 'Issues' section on LUKS website.
|
||||
Please attach the output of the failed command with the
|
||||
\-\-debug option added.
|
||||
.SH AUTHORS
|
||||
Cryptsetup-reencrypt was written by Milan Broz <gmazyland@gmail.com>.
|
||||
.SH COPYRIGHT
|
||||
Copyright \(co 2012 Milan Broz
|
||||
.br
|
||||
Copyright \(co 2012 Red Hat, Inc.
|
||||
|
||||
This is free software; see the source for copying conditions. There is NO
|
||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
.SH SEE ALSO
|
||||
The project website at \fBhttp://code.google.com/p/cryptsetup/\fR
|
||||
855
man/cryptsetup.8
855
man/cryptsetup.8
@@ -1,215 +1,826 @@
|
||||
.TH CRYPTSETUP "8" "March 2005" "cryptsetup" "Maintenance Commands"
|
||||
.TH CRYPTSETUP "8" "May 2012" "cryptsetup" "Maintenance Commands"
|
||||
.SH NAME
|
||||
cryptsetup - setup cryptographic volumes for dm-crypt (including LUKS extension)
|
||||
cryptsetup - manage plain dm-crypt and LUKS encrypted volumes
|
||||
.SH SYNOPSIS
|
||||
|
||||
.B cryptsetup <options> <action> <action args>
|
||||
|
||||
.SH DESCRIPTION
|
||||
.\" Add any additional description here
|
||||
.PP
|
||||
cryptsetup is used to conveniently setup dm-crypt managed device-mapper mappings. For basic dm-crypt mappings, there are five operations.
|
||||
.SH ACTIONS
|
||||
These strings are valid for \fB<action>\fR, followed by their \fB<action args>\fR:
|
||||
cryptsetup is used to conveniently setup dm-crypt managed
|
||||
device-mapper mappings. These include plain dm-crypt volumes and
|
||||
LUKS volumes. The difference is that LUKS uses a metadata header
|
||||
and can hence offer more features than plain dm-crypt. On the other
|
||||
hand, the header is visible and vulnerable to damage.
|
||||
.SH WARNINGS
|
||||
.PP
|
||||
A lot of good information on the risks of using encrypted storage,
|
||||
on handling problems and on security aspects can be found in the
|
||||
\fICryptsetup FAQ\fR. Read it. Nonetheless, some risks deserve
|
||||
to be mentioned here.
|
||||
|
||||
\fBBackup:\fR Storage media die. Encryption has no influence on that.
|
||||
Backup is mandatory for encrypted data as well, if the data has any
|
||||
worth. See the Cryptsetup FAQ for advice on how to do backup of an
|
||||
encrypted volume.
|
||||
|
||||
\fBCharacter encoding:\fR If you enter a
|
||||
passphrase with special symbols, the passphrase can change
|
||||
depending character encoding. Keyboard settings can also change,
|
||||
which can make blind input hard or impossible. For
|
||||
example, switching from some ASCII 8-bit variant to UTF-8
|
||||
can lead to a different binary encoding and hence different
|
||||
passphrase seen by cryptsetup, even if what you see on
|
||||
the terminal is exactly the same. It is therefore highly
|
||||
recommended to select passphrase characters only from 7-bit
|
||||
ASCII, as the encoding for 7-bit ASCII stays the same for
|
||||
all ASCII variants and UTF-8.
|
||||
|
||||
\fBLUKS header:\fR If the header of a LUKS volume gets damaged,
|
||||
all data is permanently lost unless you have a header-backup.
|
||||
If a key-slot is damaged, it can only be restored from a header-backup
|
||||
or if another active key-slot with known passphrase is undamaged.
|
||||
Damaging the LUKS header is something people manage to do with
|
||||
surprising frequency. This risk is the result of a trade-off
|
||||
between security and safety, as LUKS is designed for fast and
|
||||
secure wiping by just overwriting header and key-slot area.
|
||||
|
||||
.SH PLAIN MODE
|
||||
Plain dm-crypt encrypts the device sector-by-sector with a
|
||||
single, non-salted hash of the passphrase. No checks
|
||||
are performed, no metadata is used. There is no formatting operation.
|
||||
When the raw device is mapped (created), the usual device operations
|
||||
can be used on the mapped device, including filesystem creation.
|
||||
Mapped devices usually reside in /dev/mapper/<name>.
|
||||
|
||||
There are four operations:
|
||||
|
||||
\fIcreate\fR <name> <device>
|
||||
.IP
|
||||
creates a mapping with <name> backed by device <device>.
|
||||
<options> can be [\-\-hash, \-\-cipher, \-\-verify-passphrase, \-\-key-file, \-\-key-size, \-\-offset, \-\-skip, \-\-readonly]
|
||||
Creates a mapping with <name> backed by device <device>.
|
||||
|
||||
\fB<options>\fR can be [\-\-hash, \-\-cipher, \-\-verify-passphrase,
|
||||
\-\-key-file, \-\-keyfile-offset, \-\-key-size, \-\-offset, \-\-skip, \-\-size,
|
||||
\-\-readonly, \-\-shared, \-\-allow-discards]
|
||||
|
||||
Example: 'cryptsetup create e1 /dev/sda10' maps the raw
|
||||
encrypted device /dev/sda10 to the mapped (decrypted) device
|
||||
/dev/mapper/e1, which can then be mounted, fsck-ed or have a
|
||||
filesystem created on it.
|
||||
.PP
|
||||
\fIremove\fR <name>
|
||||
.IP
|
||||
removes an existing mapping <name>. No options.
|
||||
Removes the existing mapping <name> and wipes the key from kernel memory.
|
||||
.PP
|
||||
\fIstatus\fR <name>
|
||||
.IP
|
||||
reports the status for the mapping <name>. No options.
|
||||
Reports the status for the mapping <name>.
|
||||
.PP
|
||||
\fIresize\fR <name>
|
||||
.IP
|
||||
resizes an active mapping <name>. <options> must include \-\-size
|
||||
.PP
|
||||
.br
|
||||
Resizes an active mapping <name>.
|
||||
|
||||
If \-\-size (in sectors) is not specified, the size of the
|
||||
underlying block device is used. Note that this does not
|
||||
change the raw device geometry, it just changes how many
|
||||
sectors of the raw device are represented in the mapped device.
|
||||
.SH LUKS EXTENSION
|
||||
LUKS, the Linux Unified Key Setup, is a standard for disk encryption.
|
||||
It adds a standardized header at the start of the device,
|
||||
a key-slot area directly behind the header and the bulk
|
||||
data area behind that. The whole set is called a 'LUKS container'.
|
||||
The device that a LUKS container resides on is called a 'LUKS device'.
|
||||
For most purposes both terms can be used interchangeably. But
|
||||
note that when the LUKS header is at a nonzero offset
|
||||
in a device, then the device is not a LUKS device anymore, but
|
||||
has a LUKS container stored in it at an offset.
|
||||
|
||||
LUKS, Linux Unified Key Setup, is a standard for hard disk encryption. It standardizes a partition header, as well as the format of the bulk data. LUKS can manage multiple passwords, that can be revoked effectively and that are protected against dictionary attacks with PBKDF2.
|
||||
LUKS can manage multiple passphrases that can be individually revoked
|
||||
or changed and that can be securely scrubbed from persistent
|
||||
media due to the use of anti-forensic stripes. Passphrases
|
||||
are protected against brute-force and dictionary
|
||||
attacks by PBKDF2, which implements hash iteration and salting
|
||||
in one function.
|
||||
|
||||
These are valid LUKS actions:
|
||||
Each passphrase, also called a
|
||||
.B key
|
||||
in this document, is associated with one of 8 key-slots.
|
||||
Key operations that do not specify a slot affect the first slot
|
||||
that matches the supplied passphrase or the first empty slot if
|
||||
a new passphrase is added.
|
||||
|
||||
The following are valid LUKS actions:
|
||||
|
||||
\fIluksFormat\fR <device> [<key file>]
|
||||
.IP
|
||||
initializes a LUKS partition and sets the initial key, either via prompting or via <key file>.
|
||||
<options> can be [\-\-cipher, \-\-verify-passphrase, \-\-key-size, \-\-key-slot].
|
||||
Initializes a LUKS partition and sets the initial passphrase
|
||||
(for key-slot 0),
|
||||
either via prompting or via <key file>. Note that
|
||||
if the second argument is present, then the passphrase
|
||||
is taken from the file given there, without the need
|
||||
to use the \-\-key-file option. Also note that for both forms
|
||||
of reading the passphrase from file you can
|
||||
give '-' as file name, which results in the passphrase being read
|
||||
from stdin and the safety-question being skipped.
|
||||
|
||||
You can only call luksFormat on a LUKS device that is not mapped.
|
||||
|
||||
\fB<options>\fR can be [\-\-cipher, \-\-verify-passphrase, \-\-key-size,
|
||||
\-\-key-slot, \-\-key-file (takes precedence over optional second argument),
|
||||
\-\-keyfile-offset, \-\-keyfile-size, \-\-use-random | \-\-use-urandom,
|
||||
\-\-uuid,
|
||||
\-\-master-key-file].
|
||||
|
||||
\fBWARNING:\fR Doing a luksFormat on an existing LUKS container will
|
||||
make all data the old container permanently irretrievable, unless
|
||||
you have a header backup.
|
||||
.PP
|
||||
\fIluksOpen\fR <device> <name>
|
||||
.IP
|
||||
opens the LUKS partition <device> and sets up a mapping <name> after successful verification of the supplied key material (either via key file by \-\-key-file, or via prompting).
|
||||
<options> can be [\-\-key-file, \-\-readonly].
|
||||
Opens the LUKS device <device> and sets up a mapping <name> after
|
||||
successful verification of the supplied passphrase.
|
||||
If the passphrase is not supplied via \-\-key-file, the command
|
||||
prompts for it interactively.
|
||||
|
||||
The <device> parameter can be also specified by LUKS UUID in the
|
||||
format UUID=<uuid>, which uses the symlinks in /dev/disk/by-uuid.
|
||||
|
||||
\fB<options>\fR can be [\-\-key-file, \-\-keyfile-offset,
|
||||
\-\-keyfile-size, \-\-readonly, \-\-test-passphrase,
|
||||
\-\-allow-discards, \-\-header, \-\-key-slot, \-\-master-key-file].
|
||||
.PP
|
||||
\fIluksClose\fR <name>
|
||||
.IP
|
||||
identical to \fIremove\fR.
|
||||
.PP
|
||||
\fIluksAddKey\fR <device> [<new key file>]
|
||||
\fIluksSuspend\fR <name>
|
||||
.IP
|
||||
add a new key file/passphrase. An existing passphrase or key file (via \-\-key-file) must be supplied. The key file with the new material is supplied as a positional argument. <options> can be [\-\-key-file, \-\-key-slot].
|
||||
Suspends an active device (all IO operations will blocked
|
||||
and accesses to the device will wait indefinitely)
|
||||
and wipes the encryption
|
||||
key from kernel memory. Needs kernel 2.6.19 or later.
|
||||
|
||||
After this operation you have to use \fIluksResume\fR to reinstate
|
||||
the encryption key and unblock the device or \fIluksClose\fR to remove
|
||||
the mapped device.
|
||||
|
||||
\fBWARNING:\fR never suspend the device on which the cryptsetup binary resides.
|
||||
|
||||
\fB<options>\fR can be [\-\-header].
|
||||
.PP
|
||||
\fIluksRemoveKey\fR <device> [<key file>]
|
||||
\fIluksResume\fR <name>
|
||||
.IP
|
||||
remove supplied key or key file from LUKS device
|
||||
Resumes a suspended device and reinstates the encryption key.
|
||||
Prompts interactively for a passphrase if \-\-key-file is not given.
|
||||
|
||||
\fB<options>\fR can be [\-\-key-file, \-\-keyfile-size, \-\-header]
|
||||
.PP
|
||||
\fIluksAddKey\fR <device> [<key file with new key>]
|
||||
.IP
|
||||
adds a new passphrase. An existing passphrase must be supplied
|
||||
interactively or via \-\-key-file.
|
||||
The new passphrase to be added can be specified interactively
|
||||
or read from the file given as positional argument.
|
||||
|
||||
\fB<options>\fR can be [\-\-key-file, \-\-keyfile-offset,
|
||||
\-\-keyfile-size, \-\-new-keyfile-offset,
|
||||
\-\-new-keyfile-size, \-\-key-slot, \-\-master-key-file].
|
||||
.PP
|
||||
\fIluksRemoveKey\fR <device> [<key file with passphrase to be removed>]
|
||||
.IP
|
||||
Removes the supplied passphrase from the LUKS device. The
|
||||
passphrase to be removed can be specified interactively,
|
||||
as positional argument or via \-\-key-file.
|
||||
|
||||
\fB<options>\fR can be [\-\-key-file, \-\-keyfile-offset,
|
||||
\-\-keyfile-size]
|
||||
|
||||
\fBWARNING:\fR If you read the passphrase from stdin
|
||||
(without further argument or with '-' as argument
|
||||
to \-\-key-file), batch-mode (-q) will be implicitely
|
||||
switched on and no warning will be given when you remove the
|
||||
last remaining passphrase from a LUKS container. Removing
|
||||
the last passphrase makes the LUKS container permanently
|
||||
inaccessible.
|
||||
.PP
|
||||
\fIluksChangeKey\fR <device> [<new key file>]
|
||||
.IP
|
||||
Changes an existing passphrase. The passphrase
|
||||
to be changed must be supplied interactively or via \-\-key-file.
|
||||
The new passphrase can be supplied interactively or in
|
||||
a file given as positional argument.
|
||||
|
||||
If a key-slot is specified (via \-\-key-slot), the passphrase
|
||||
for that key-slot must be given and the new passphrase
|
||||
will overwrite the specified key-slot. If no key-slot
|
||||
is specified and there is still a free key-slot, then
|
||||
the new passphrase will be put into a free key-slot before the
|
||||
key-slot containing the old passphrase is purged. If there is
|
||||
no free key-slot, then the key-slot with the old passphrase is
|
||||
overwritten directly.
|
||||
|
||||
\fBWARNING:\fR If a key-slot is overwritten, a media failure
|
||||
during this operation can cause the overwrite to fail after
|
||||
the old passphrase has been wiped and make the LUKS container
|
||||
inaccessible.
|
||||
|
||||
\fB<options>\fR can be [\-\-key-file, \-\-keyfile-offset,
|
||||
\-\-keyfile-size, \-\-new-keyfile-offset,
|
||||
\-\-new-keyfile-size, \-\-key-slot].
|
||||
.PP
|
||||
\fIluksKillSlot\fR <device> <key slot number>
|
||||
.IP
|
||||
wipe key with number <key slot> from LUKS device. A remaining passphrase or key file (via \-\-key-file) must be supplied. <options> can be [\-\-key-file].
|
||||
.PP
|
||||
\fIluksDelKey\fR <device> <key slot number>
|
||||
.IP
|
||||
identical to luksKillSlot, but deprecated action name.
|
||||
Wipe the key-slot number <key slot> from the LUKS device. A remaining
|
||||
passphrase must be supplied, either interactively or via \-\-key-file.
|
||||
This command can remove the last remaining key-slot, but requires
|
||||
an interactive confirmation when doing so. Removing the last
|
||||
passphrase makes a LUKS container permanently inaccessible.
|
||||
|
||||
\fB<options>\fR can be [\-\-key-file, \-\-keyfile-offset, \-\-keyfile-size].
|
||||
|
||||
\fBWARNING:\fR If you read the passphrase from stdin
|
||||
(without further argument or with '-' as argument
|
||||
to \-\-key-file), batch-mode (-q) will be implicitely
|
||||
switched on and no warning will be given when you remove the
|
||||
last remaining passphrase from a LUKS container. Removing
|
||||
the last passphrase makes the LUKS container permanently
|
||||
inaccessible.
|
||||
.PP
|
||||
\fIluksUUID\fR <device>
|
||||
.IP
|
||||
print UUID, if <device> has a LUKS header. No options.
|
||||
Print the UUID of a LUKS device.
|
||||
.br
|
||||
Set new UUID if \fI\-\-uuid\fR option is specified.
|
||||
.PP
|
||||
\fIisLuks\fR <device>
|
||||
.IP
|
||||
returns true, if <device> is a LUKS partition. Otherwise, false. No options.
|
||||
Returns true, if <device> is a LUKS device, false otherwise.
|
||||
Use option \-v to get human-readable feedback. 'Command successful.'
|
||||
means the device is a LUKS device.
|
||||
.PP
|
||||
\fIluksDump\fR <device>
|
||||
.IP
|
||||
dumps the header information of a LUKS partition. No options.
|
||||
Dump the header information of a LUKS device.
|
||||
|
||||
If the \-\-dump-master-key option is used, the LUKS device master key is
|
||||
dumped instead of the keyslot info. Beware that the master key cannot be
|
||||
changed and can be used to decrypt the data stored in the LUKS container
|
||||
without a passphrase and even without the LUKS header. This means
|
||||
that if the master key is compromised, the whole device has to be
|
||||
erased to prevent further access. Use this option carefully.
|
||||
|
||||
In order to dump the master key, a passphrase has to be supplied,
|
||||
either interactively or via \-\-key-file.
|
||||
|
||||
\fB<options>\fR can be [\-\-dump-master-key, \-\-key-file,
|
||||
\-\-keyfile-offset, \-\-keyfile-size].
|
||||
|
||||
\fBWARNING:\fR If \-\-dump-master-key is used with \-\-key-file
|
||||
and the argument to \-\-key-file is '-', no validation question
|
||||
will be asked and no warning given.
|
||||
.PP
|
||||
\fIluksHeaderBackup\fR <device> \-\-header-backup-file <file>
|
||||
.IP
|
||||
Stores a binary backup of the LUKS header and keyslot area.
|
||||
.br
|
||||
Note: Using '-' as filename writes the header backup to a file named '-'.
|
||||
|
||||
For more information about LUKS, see \fBhttp://code.google.com/p/cryptsetup/wiki/Specification\fR
|
||||
\fBWARNING:\fR This backup file and a passphrase valid
|
||||
at the time of backup allows decryption of the
|
||||
LUKS data area, even if the passphrase was later changed or
|
||||
removed from the LUKS device. Also note that with a header
|
||||
backup you lose the ability to securely wipe the LUKS
|
||||
device by just overwriting the header and key-slots. You
|
||||
either need to securely erase all header backups in
|
||||
addition or overwrite the encrypted data area as well.
|
||||
The second option is less secure, as some sectors
|
||||
can survive, e.g. due to defect management.
|
||||
.PP
|
||||
\fIluksHeaderRestore\fR <device> \-\-header-backup-file <file>
|
||||
.IP
|
||||
Restores a binary backup of the LUKS header and keyslot area
|
||||
from the specified file.
|
||||
.br
|
||||
Note: Using '-' as filename reads the header backup from a file named '-'.
|
||||
|
||||
\fBWARNING:\fR Header and keyslots will be replaced, only
|
||||
the passphrases from the backup will work afterwards.
|
||||
|
||||
This command requires that the master key size and data offset
|
||||
of the LUKS header already on the device and of the header backup
|
||||
match. Alternatively, if there is no LUKS header on the device,
|
||||
the backup will also be written to it.
|
||||
.PP
|
||||
\fIrepair\fR <device>
|
||||
.IP
|
||||
Tries to repair the LUKS device metadata if possible.
|
||||
|
||||
This command is useful to fix some known benign LUKS metadata
|
||||
header corruptions. Only basic corruptions of unused keyslot
|
||||
are fixable. This command will only change the LUKS header, not
|
||||
any key-slot data.
|
||||
|
||||
\fBWARNING:\fR Always create a binary backup of the original
|
||||
header before calling this command.
|
||||
.SH loop-AES EXTENSION
|
||||
cryptsetup supports mapping loop-AES encrypted partition using
|
||||
a compatibility mode.
|
||||
.PP
|
||||
\fIloopaesOpen\fR <device> <name> \-\-key-file <keyfile>
|
||||
.IP
|
||||
Opens the loop-AES <device> and sets up a mapping <name>.
|
||||
|
||||
If the key file is encrypted with GnuPG, then you have to use
|
||||
\-\-key-file=- and decrypt it before use, e.g. like this:
|
||||
.br
|
||||
gpg \-\-decrypt <keyfile> | cryptsetup loopaesOpen \-\-key-file=- <device> <name>
|
||||
|
||||
Use \fB\-\-key-file-size\fR to specify the proper key length if needed.
|
||||
|
||||
Use \fB\-\-offset\fR to specify device offset. Note that the units
|
||||
need to be specified in number of 512 byte sectors.
|
||||
|
||||
Use \fB\-\-skip\fR to specify the IV offset. If the original device
|
||||
used an offset and but did not use it in IV sector calculations,
|
||||
you have to explicitly use \fB\-\-skip 0\fR in addition to the offset
|
||||
parameter.
|
||||
|
||||
Use \fB\-\-hash\fR to override the default hash function for
|
||||
passphrase hashing (otherwise it is detected according to key
|
||||
size).
|
||||
|
||||
\fB<options>\fR can be [\-\-key-file, \-\-key-size, \-\-offset, \-\-skip,
|
||||
\-\-hash, \-\-readonly, \-\-allow-discards].
|
||||
.PP
|
||||
\fIloopaesClose\fR <name>
|
||||
.IP
|
||||
Identical to \fIremove\fR.
|
||||
.PP
|
||||
See also section 7 of the FAQ and \fBhttp://loop-aes.sourceforge.net\fR
|
||||
for more information regarding loop-AES.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B "\-\-hash, \-h"
|
||||
specifies hash to use for password hashing. This option is only relevant for \fIcreate\fR action. The hash string is passed to libgcrypt, so all hashes accepted by gcrypt are supported. Default is "ripemd160".
|
||||
.B "\-\-verbose, \-v"
|
||||
Print more information on command execution.
|
||||
.TP
|
||||
.B "\-\-cipher, \-c"
|
||||
set cipher specification string. For plain dm-crypt mappings, the default is "aes-cbc-plain", for LUKS mappings it's "aes-cbc-essiv:sha256". For pre-2.6.10 kernels, use "aes-plain" as they don't understand the new cipher spec strings. To use ESSIV, use "aes-cbc-essiv:sha256".
|
||||
.B "\-\-debug"
|
||||
Run in debug mode with full diagnostic logs. Debug output
|
||||
lines are always prefixed by '#'.
|
||||
.TP
|
||||
.B "\-\-hash, \-h \fI<hash-spec>\fR"
|
||||
Specifies the passphrase hash for \fIcreate\fR and \fIloopaesOpen\fR.
|
||||
|
||||
For XTS mode, kernel version 2.6.24 or more recent is required. Use "aes-xts-plain" cipher specification and set key size to 256 (or 512) bits (see \-s option).
|
||||
Specifies the hash used in the LUKS key setup scheme and volume key digest
|
||||
for \fIluksFormat\fR.
|
||||
|
||||
The specified hash name is passed to the compiled-in crypto backend.
|
||||
Different backends may support different hashes.
|
||||
For \fIluksFormat\fR, the hash
|
||||
algorithm must provide at least 160 bits of output, which
|
||||
excludes, e.g., MD5. Do not use a non-crypto hash like
|
||||
\fB"crc32"\fR as this breaks security.
|
||||
|
||||
Values compatible with old version of cryptsetup are
|
||||
\fB"ripemd160"\fR for \fIcreate\fR and
|
||||
\fB"sha1"\fR for \fIluksFormat\fR.
|
||||
|
||||
Use \fIcryptsetup \-\-help\fR to show the defaults.
|
||||
.TP
|
||||
.B "\-\-cipher, \-c \fI<cipher-spec>\fR"
|
||||
Set the cipher specification string.
|
||||
|
||||
\fIcryptsetup \-\-help\fR shows the compiled-in defaults.
|
||||
The current default in the distributed sources is
|
||||
"aes-cbc-essiv:sha256" for both plain dm-crypt and LUKS.
|
||||
|
||||
For XTS mode (a possible future default), use "aes-xts-plain"
|
||||
or better "aes-xts-plain64"
|
||||
as cipher specification and optionally set a key size of
|
||||
512 bits with the \-s option. Key size for XTS
|
||||
mode is twice that for other modes for the same
|
||||
security level.
|
||||
|
||||
XTS mode requires kernel 2.6.24 or later and plain64 requires
|
||||
kernel 2.6.33 or later. More information can be found in the FAQ.
|
||||
.TP
|
||||
.B "\-\-verify-passphrase, \-y"
|
||||
query for passwords twice. Useful when creating a (regular) mapping for the first time, or when running \fIluksFormat\fR.
|
||||
When interactively asking for a passphrase, ask for it twice
|
||||
and complain if both inputs do not match. Advised when creating
|
||||
a regular mapping for the first time, or when running
|
||||
\fIluksFormat\fR. Ignores on input from file or stdin.
|
||||
.TP
|
||||
.B "\-\-key-file, \-d"
|
||||
use file as key material. With LUKS, key material supplied in key files via \-d are always used for existing passphrases. If you want to set a new key via a key file, you have to use a positional arg to \fIluksFormat\fR or \fIluksAddKey\fR.
|
||||
.B "\-\-key-file, \-d \fIname\fR"
|
||||
Read the passphrase from file.
|
||||
|
||||
If the key file is "-", stdin will be used. This is different from how cryptsetup usually reads from stdin. See section \fBNOTES ON PASSWORD PROCESSING\fR for more information.
|
||||
If the name given is "-", then the passphrase will be read from stdin.
|
||||
In this case, reading will not stop at newline characters.
|
||||
|
||||
With LUKS, passphrases supplied via \-\-key-file are always
|
||||
the existing passphrases requested by a command, except in
|
||||
the case of \fIluksFormat\fR where \-\-key-file is equivalent
|
||||
to the positional key file argument.
|
||||
|
||||
If you want to set a new passphrase via key file, you have to
|
||||
use a positional argument to \fIluksAddKey\fR.
|
||||
|
||||
See section \fBNOTES ON PASSPHRASE PROCESSING\fR for more information.
|
||||
.TP
|
||||
.B "\-\-key-slot, \-S"
|
||||
For LUKS operations that add key material, this options allows to you specify which key slot is selected for the new key. This option can be used for \fIluksFormat\fR and \fIluksAddKey\fR.
|
||||
.B "\-\-keyfile-offset \fIvalue\fR"
|
||||
Skip \fIvalue\fR bytes at the beginning of the key file.
|
||||
Works with all commands that accepts key files.
|
||||
.TP
|
||||
.B "\-\-key-size, \-s"
|
||||
set key size in bits. Has to be a multiple of 8 bits. The key size is limited by the used cipher. See output of /proc/crypto for more information. Can be used for \fIcreate\fR or \fIluksFormat\fR, all other LUKS actions will ignore this flag, as the key-size is specified by the partition header. Default is 128 for \fIluksFormat\fR and 256 for \fIcreate\fR.
|
||||
.B "\-\-keyfile-size, \-l \fIvalue\fR"
|
||||
Read a maximum of \fIvalue\fR bytes from the key file.
|
||||
Default is to read the whole file up to the compiled-in
|
||||
maximum that can be queried with \-\-help. Supplying more
|
||||
data than the compiled-in maximum aborts the operation.
|
||||
|
||||
This option is useful
|
||||
to cut trailing newlines, for example. If \-\-keyfile-offset
|
||||
is also given, the size count starts after the offset.
|
||||
Works with all commands that accepts key files.
|
||||
.TP
|
||||
.B "\-\-size, \-b"
|
||||
force the size of the underlying device in sectors.
|
||||
This option is only relevant for \fIcreate\fR and \fIresize\fR action.
|
||||
.B "\-\-new-keyfile-offset \fIvalue\fR"
|
||||
Skip \fIvalue\fR bytes at the start when
|
||||
adding a new passphrase from key file with
|
||||
\fIluksAddKey\fR.
|
||||
.TP
|
||||
.B "\-\-offset, \-o"
|
||||
start offset in the backend device.
|
||||
This option is only relevant for \fIcreate\fR action.
|
||||
.B "\-\-new-keyfile-size \fIvalue\fR"
|
||||
Read a maximum of \fIvalue\fR bytes when adding
|
||||
a new passphrase from key file with \fIluksAddKey\fR.
|
||||
Default is to read the whole file up to the compiled-in
|
||||
maximum length that can be queried with \-\-help.
|
||||
Supplying more than the compiled in maximum aborts the
|
||||
operation.
|
||||
When \-\-new-keyfile-offset is also given, reading starts
|
||||
after the offset.
|
||||
.TP
|
||||
.B "\-\-skip, \-p"
|
||||
how many sectors of the encrypted data to skip at the beginning. This is different from the \-\-offset options with respect to IV calculations. Using \-\-offset will shift the IV calculation by the same negative amount. Hence, if \-\-offset \fIn\fR, sector \fIn\fR will be the first sector on the mapping with IV \fI0\fR. Using \-\-skip would have resulted in sector \fIn\fR being the first sector also, but with IV \fIn\fR.
|
||||
This option is only relevant for \fIcreate\fR action.
|
||||
.B "\-\-master-key-file"
|
||||
Use a master key stored in a file.
|
||||
|
||||
For \fIluksFormat\fR this
|
||||
allows creating a LUKS header with this specific
|
||||
master key. If the master key was taken from an existing
|
||||
LUKS header and all other parameters are the same,
|
||||
then the new header decrypts the data encrypted with the
|
||||
header the master key was taken from.
|
||||
|
||||
For \fIluksAddKey\fR this allows adding a new passphrase
|
||||
without having to know an exiting one.
|
||||
|
||||
For \fIluksOpen\fR this allows to open the LUKS device
|
||||
without giving a passphrase.
|
||||
.TP
|
||||
.B "\-\-readonly"
|
||||
.B "\-\-dump-master-key"
|
||||
For \fIluksDump\fR this option includes the master key in the displayed
|
||||
information. Use with care, as the master key can be used to
|
||||
bypass the passphrases, see also option \-\-master-key-file.
|
||||
.TP
|
||||
.B "\-\-use-random"
|
||||
.TP
|
||||
.B "\-\-use-urandom"
|
||||
For \fIluksFormat\fR these options define which kernel random number
|
||||
generator will be used to create the master key (which is a
|
||||
long-term key).
|
||||
|
||||
See \fBNOTES ON RANDOM NUMBER GENERATORS\fR for more
|
||||
information. Use \fIcryptsetup \-\-help\fR
|
||||
to show the compiled-in default random number generator.
|
||||
|
||||
\fBWARNING:\fR In a low-entropy situation (e.g. in an
|
||||
embedded system), both selections are problematic.
|
||||
Using /dev/urandom can lead to weak keys.
|
||||
Using /dev/random can block a long time, potentially
|
||||
forever, if not enough entropy can be harvested by
|
||||
the kernel.
|
||||
.TP
|
||||
.B "\-\-key-slot, \-S <0-7>"
|
||||
For LUKS operations that add key material, this options allows you
|
||||
to specify which key slot is selected for the new key.
|
||||
This option can be used for \fIluksFormat\fR,
|
||||
and \fIluksAddKey\fR.
|
||||
.br
|
||||
In addition, for \fIluksOpen\fR, this option selects a
|
||||
specific key-slot to compare the passphrase against.
|
||||
If the given passphrase would only match a different key-slot,
|
||||
the operation fails.
|
||||
.TP
|
||||
.B "\-\-key-size, \-s <bits>"
|
||||
Sets key size in bits. The argument has to be a multiple of
|
||||
8. The possible key-sizes are limited by the cipher and
|
||||
mode used.
|
||||
|
||||
See /proc/crypto for more information. Note that key-size
|
||||
in /proc/crypto is stated in bytes.
|
||||
|
||||
This option can be used for \fIcreate\fR or \fIluksFormat\fR. All
|
||||
other LUKS actions will use the key-size specified in the LUKS header.
|
||||
Use \fIcryptsetup \-\-help\fR to show the compiled-in defaults.
|
||||
.TP
|
||||
.B "\-\-size, \-b <number of 512 byte sectors>"
|
||||
Force the size of the underlying device in sectors of 512 bytes.
|
||||
This option is only relevant for the \fIcreate\fR and \fIresize\fR
|
||||
actions.
|
||||
.TP
|
||||
.B "\-\-offset, \-o <number of 512 byte sectors>"
|
||||
Start offset in the backend device in 512-byte sectors.
|
||||
This option is only relevant for the \fIcreate\fR and \fIloopaesOpen\fR
|
||||
actions.
|
||||
.TP
|
||||
.B "\-\-skip, \-p <number of 512 byte sectors>"
|
||||
How many sectors of the encrypted data to skip at the beginning.
|
||||
This option is only relevant for \fIcreate\fR and \fIloopaesOpen\fR action.
|
||||
|
||||
This is different from the \-\-offset options with respect to
|
||||
the sector numbers used in IV calculation.
|
||||
Using \-\-offset will shift the IV calculation by the same negative amount.
|
||||
Hence, if \-\-offset \fIn\fR, sector \fIn\fR will get a sector
|
||||
number of \fI0\fR for the IV calculation.
|
||||
Using \-\-skip causes sector \fIn\fR to also be the first sector
|
||||
of the mapped device, but with its number for IV generation is \fIn\fR.
|
||||
.TP
|
||||
.B "\-\-readonly, \-r"
|
||||
set up a read-only mapping.
|
||||
.TP
|
||||
.B "\-\-iter-time, \-i"
|
||||
The number of milliseconds to spend with PBKDF2 password processing. This option is only relevant to the LUKS operations as \fIluksFormat\fR or \fIluksAddKey\fR.
|
||||
.B "\-\-shared"
|
||||
Creates an additional mapping for one common
|
||||
ciphertext device. Arbitrary mappings are supported.
|
||||
This option is only relevant for the
|
||||
\fIcreate\fR action. Use \-\-offset, \-\-size and \-\-skip to
|
||||
specify the mapped area.
|
||||
.TP
|
||||
.B "\-\-iter-time, \-i <number of milliseconds>"
|
||||
The number of milliseconds to spend with PBKDF2 passphrase processing.
|
||||
This option is only relevant for LUKS operations that set or change
|
||||
passphrases, such as \fIluksFormat\fR or \fIluksAddKey\fR.
|
||||
Specifying 0 as parameter selects the compiled-in default.
|
||||
.TP
|
||||
.B "\-\-batch-mode, \-q"
|
||||
Do not ask for confirmation. Use with care! This option is only relevant for \fIluksFormat\fR,\fIluksAddKey\fR,\fIluksRemoveKey\fR or \fIluksKillSlot\fR.
|
||||
Suppresses all confirmation questions. Use with care!
|
||||
|
||||
If the \-y option is not specified, this option also switches off
|
||||
the passphrase verification for \fIluksFormat\fR.
|
||||
.TP
|
||||
.B "\-\-timeout, \-t"
|
||||
The number of seconds to wait before timeout. This option is relevant every time a password is asked, like \fIcreate\fR, \fIluksOpen\fR, \fIluksFormat\fR or \fIluksAddKey\fR. It has no effect if used in conjunction with \-\-key-file.
|
||||
.B "\-\-timeout, \-t <number of seconds>"
|
||||
The number of seconds to wait before timeout on passphrase input
|
||||
via terminal. It is relevant every time a passphrase is asked,
|
||||
for example for \fIcreate\fR, \fIluksOpen\fR, \fIluksFormat\fR
|
||||
or \fIluksAddKey\fR. It has no effect if used in conjunction
|
||||
with \-\-key-file.
|
||||
.br
|
||||
This option is useful when the system
|
||||
should not stall if the user does not input a passphrase,
|
||||
e.g. during boot. The default is a value of 0 seconds,
|
||||
which means to wait forever.
|
||||
.TP
|
||||
.B "\-\-tries, \-T"
|
||||
How often the input of the passphrase shall be retried. This option is relevant every time a password is asked, like \fIcreate\fR, \fIluksOpen\fR, \fIluksFormat\fR or \fIluksAddKey\fR. The default is 3 tries.
|
||||
How often the input of the passphrase shall be retried.
|
||||
This option is relevant
|
||||
every time a passphrase is asked, for example for
|
||||
\fIcreate\fR, \fIluksOpen\fR, \fIluksFormat\fR
|
||||
or \fIluksAddKey\fR. The default is 3 tries.
|
||||
.TP
|
||||
.B "\-\-align-payload=\fIvalue\fR"
|
||||
Align payload at a boundary of \fIvalue\fR 512-byte sectors. This option is relevant for \fIluksFormat\fR. If your block device lives on a RAID, it is
|
||||
useful to align the filesystem at full stripe boundaries so it can take advantage of the RAID's geometry. See for instance the sunit and swidth options
|
||||
in the mkfs.xfs manual page. By default, the payload is aligned at an 8 sector (4096 byte) boundary.
|
||||
.B "\-\-align-payload <number of 512 byte sectors>"
|
||||
Align payload at a boundary of \fIvalue\fR 512-byte sectors.
|
||||
This option is relevant for \fIluksFormat\fR.
|
||||
|
||||
If not specified, cryptsetup tries to use the topology info
|
||||
provided by kernel for the underlying device to get optimal alignment.
|
||||
If not available (or the calculated value is a multiple of the default)
|
||||
data is by default aligned to a 1MiB boundary (i.e. 2048 512-byte sectors).
|
||||
|
||||
For a detached LUKS header this option specifies the offset on the
|
||||
data device. See also the \-\-header option.
|
||||
.TP
|
||||
.B "\-\-uuid=\fIUUID\fR"
|
||||
Use the provided \fIUUID\fR for the \fIluksFormat\fR command
|
||||
instead of generating new one. Changes the existing UUID when
|
||||
used with the \fIluksUUID\fR command.
|
||||
|
||||
The UUID must be provided in the standard UUID format,
|
||||
e.g. 12345678-1234-1234-1234-123456789abc.
|
||||
.TP
|
||||
.B "\-\-allow-discards\fR"
|
||||
Allow the use of discard (TRIM) requests for device.
|
||||
This option is only relevant for \fIcreate\fR, \fIluksOpen\fR
|
||||
and \fIloopaesOpen\fR.
|
||||
|
||||
\fBWARNING:\fR This command can have a negative security impact
|
||||
because it can make filesystem-level operations visible on
|
||||
the physical device. For example, information leaking
|
||||
filesystem type, used space, etc. may be extractable from
|
||||
the physical device if the discarded blocks can be located
|
||||
later. If in doubt, do no use it.
|
||||
|
||||
A kernel version of 3.1 or later is needed. For earlier kernels
|
||||
this option is ignored.
|
||||
.TP
|
||||
.B "\-\-test-passphrase\fR"
|
||||
Do not activate device, just verify passphrase.
|
||||
This option is only relevant for \fIluksOpen\fR.
|
||||
.TP
|
||||
.B "\-\-header\fR <device or file storing the LUKS header>"
|
||||
Use a detached (separated) metadata device or file where the
|
||||
LUKS header is stored. This options allows to store ciphertext
|
||||
and LUKS header on different devices.
|
||||
|
||||
This option is only relevant for LUKS devices and can be
|
||||
used with the \fIluksFormat\fR, \fIluksOpen\fR, \fIluksSuspend\fR,
|
||||
\fIluksResume\fR, \fIstatus\fR and \fIresize\fR commands.
|
||||
|
||||
For \fIluksFormat\fR with a file name as argument to \-\-header,
|
||||
it has to exist and be large enough to contain the LUKS header.
|
||||
See the cryptsetup FAQ for header size calculation.
|
||||
|
||||
For other commands that change the LUKS header (e.g. \fIluksAddKey\fR),
|
||||
specify the device or file with the LUKS header directly as the
|
||||
LUKS device.
|
||||
|
||||
If used with \fIluksFormat\fR, the \-\-align-payload option is taken
|
||||
as absolute sector alignment on ciphertext device and can be zero.
|
||||
|
||||
\fBWARNING:\fR There is no check whether the ciphertext device specified
|
||||
actually belongs to the header given. In fact you can specify an
|
||||
arbitrary device as the ciphertext device for \fIluksOpen\fR
|
||||
with the \-\-header option. Use with care.
|
||||
.TP
|
||||
.B "\-\-version"
|
||||
Show the version.
|
||||
Show the program version.
|
||||
.SH RETURN CODES
|
||||
Cryptsetup returns 0 on success and a non-zero value on error.
|
||||
|
||||
.SH NOTES ON PASSWORD PROCESSING
|
||||
\fIFrom a file descriptor or a terminal\fR: Password processing is new-line sensitive, meaning the reading will stop after encountering \\n. It will process the read material (without newline) with the default hash or the hash given by \-\-hash. After hashing, it will be cropped to the key size given by \-s.
|
||||
Error codes are: 1 wrong parameters, 2 no permission (bad passphrase),
|
||||
3 out of memory, 4 wrong device specified, 5 device already exists
|
||||
or device is busy.
|
||||
.SH NOTES ON PASSPHRASE PROCESSING FOR PLAIN MODE
|
||||
Note that no iterated hashing or salting is done in plain mode.
|
||||
If hashing is done, it is a single direct hash. This means that
|
||||
low-entropy passphrases are easy to attack in plain mode.
|
||||
|
||||
\fIFrom stdin\fR: Reading will continue until EOF (so using e.g. /dev/random as stdin will not work), with the trailing newline stripped. After that the read data will be hashed with the default hash or the hash given by \-\-hash and the result will be cropped to the keysize given by \-s. If "plain" is used as an argument to the hash option, the input data will not be hashed.
|
||||
Instead, it will be zero padded (if shorter than the keysize) or truncated (if longer than the keysize) and used directly as the key. No warning will be given if the amount of data read from stdin is less than the keysize.
|
||||
\fBFrom a terminal\fR: The passphrase is read until the
|
||||
first newline, i.e. '\\n'.
|
||||
The input without the newline character is processed with
|
||||
the default hash or the hash specified with \-\-hash.
|
||||
The has result will be truncated to the key size
|
||||
of the used cipher, or the size specified with \-s.
|
||||
|
||||
\fIFrom a key file\fR: It will be cropped to the size given by \-s. If there is insufficient key material in the key file, cryptsetup will quit with an error.
|
||||
\fBFrom stdin\fR: Reading will continue until a newline (or until
|
||||
the maximum input size is reached), with the trailing newline
|
||||
stripped. The maximum input size is defined by the same
|
||||
compiled-in default as for the maximum key file size and can
|
||||
be overwritten using \-\-keyfile-size option.
|
||||
|
||||
If \-\-key-file=- is used for reading the key from stdin, no trailing newline is stripped from the input. Without that option, cryptsetup strips trailing newlines from stdin input.
|
||||
.SH NOTES ON PASSWORD PROCESSING FOR LUKS
|
||||
LUKS uses PBKDF2 to protect against dictionary attacks (see RFC 2898).
|
||||
LUKS will always use SHA1 in HMAC mode, and no other mode is supported at the moment.
|
||||
Hence, \-h is ignored.
|
||||
The data read will be hashed with the default hash
|
||||
or the hash specified with \-\-hash.
|
||||
The has result will be truncated to the key size
|
||||
of the used cipher, or the size specified with \-s.
|
||||
|
||||
LUKS will always do an exhaustive password reading. Hence, password can not be read from /dev/random, /dev/zero or any other stream that does not terminate.
|
||||
Note that if \-\-key-file=- is used for reading the key
|
||||
from stdin, trailing newlines are not stripped from the input.
|
||||
|
||||
LUKS saves the processing options when a password is set to the respective key slot.
|
||||
Therefore, no options can be given to luksOpen.
|
||||
For any password creation action (luksAddKey, or luksFormat), the user may specify how much the time the password processing should consume.
|
||||
Increasing the time will lead to a more secure password, but also will take luksOpen longer to complete. The default setting of one second is sufficient for good security.
|
||||
.SH NOTES ON PASSWORDS
|
||||
Mathematics can't be bribed. Make sure you keep your passwords safe. There are a few nice tricks for constructing a fallback, when suddenly out of (or after being) blue, your brain refuses to cooperate. These fallbacks are possible with LUKS, as it's only possible with LUKS to have multiple passwords.
|
||||
.SH AUTHORS
|
||||
cryptsetup is written by Christophe Saout <christophe@saout.de>
|
||||
.br
|
||||
LUKS extensions, and man page by Clemens Fruhwirth <clemens@endorphin.org>
|
||||
.SH "COMPATABILITY WITH OLD SUSE TWOFISH PARTITIONS"
|
||||
To read images created with SuSE Linux 9.2's loop_fish2 use \-\-cipher
|
||||
twofish-cbc-null \-s 256 \-h sha512, for images created with even
|
||||
older SuSE Linux use \-\-cipher twofish-cbc-null \-s 192 \-h
|
||||
ripemd160:20
|
||||
If "plain" is used as argument to \-\-hash, the input
|
||||
data will not be hashed. Instead, it will be zero padded (if
|
||||
shorter than the key size) or truncated (if longer than the
|
||||
key size) and used directly as the binary key. This is useful for
|
||||
directly specifying a binary key.
|
||||
No warning will be given if the amount of data read from stdin is
|
||||
less than the key size.
|
||||
|
||||
\fBFrom a key file\fR: It will be truncated to the
|
||||
key size of the used cipher or the size given by \-s
|
||||
and directly used as binary key.
|
||||
if the key file is shorter than the key, cryptsetup
|
||||
will quit with an error.
|
||||
|
||||
.SH NOTES ON PASSPHRASE PROCESSING FOR LUKS
|
||||
LUKS uses PBKDF2 to protect against dictionary attacks
|
||||
and to give some protection to low-entropy passphrases
|
||||
(see RFC 2898 and the cryptsetup FAQ).
|
||||
|
||||
\fBFrom a terminal\fR: The passphrase is read until the
|
||||
first newline and then processed by PBKDF2 without
|
||||
the newline character.
|
||||
|
||||
\fBFrom stdin\fR:
|
||||
LUKS will read passphrases from stdin up to the
|
||||
first newline character or the compiled-in
|
||||
maximum key file length. If \-\-keyfile-size is
|
||||
given, it is ignored.
|
||||
|
||||
\fBFrom key file\fR:
|
||||
The complete keyfile is read up to the compiled-in
|
||||
maximum size. Newline characters do not terminate the
|
||||
input. The \-\-keyfile-size option can be used to limit
|
||||
what is read.
|
||||
|
||||
\fBPassphrase processing\fR:
|
||||
Whenever a passphrase is added to a LUKS header (luksAddKey, luksFormat),
|
||||
the user may specify how much the time the passphrase processing
|
||||
should consume. The time is used to determine the iteration count
|
||||
for PBKDF2 and higher times will offer better protection for
|
||||
low-entropy passphrases, but luksOpen will take longer to
|
||||
complete. For passphrases that have entropy higher than the
|
||||
used key length, higher iteration times will not increase security.
|
||||
|
||||
The default setting of one second is sufficient for most
|
||||
practical cases. The only exception is a low-entropy
|
||||
passphrase used on a slow device.
|
||||
.SH INCOHERENT BEHAVIOR FOR INVALID PASSPHRASES/KEYS
|
||||
LUKS checks for a valid passphrase when an encrypted partition
|
||||
is unlocked. The behavior of plain dm-crypt is different.
|
||||
It will always decrypt with the passphrase given. If the
|
||||
given passphrase is wrong, the device mapped by plain
|
||||
dm-crypt will essentially still contain encrypted data and
|
||||
will be unreadable.
|
||||
.SH NOTES ON SUPPORTED CIPHERS, MODES, HASHES AND KEY SIZES
|
||||
The available combinations of ciphers, modes, hashes and key sizes
|
||||
depend on kernel support. See /proc/crypto for a list of available
|
||||
options. You might need to load additional kernel crypto modules
|
||||
in order to get more options.
|
||||
|
||||
For the \-\-hash option, if the crypto backend is libgcrypt,
|
||||
then all algorithms supported by the gcrypt library are available.
|
||||
For other crypto backends some algorithms may be missing.
|
||||
.SH NOTES ON PASSPHRASES
|
||||
Mathematics can't be bribed. Make sure you keep your passphrases safe.
|
||||
There are a few nice tricks for constructing a fallback, when suddenly
|
||||
out of the blue, your brain refuses to cooperate.
|
||||
These fallbacks need LUKS, as it's only possible with LUKS
|
||||
to have multiple passphrases. Still, if your attacker model does
|
||||
not prevent it, storing your passphrase in a sealed envelope somewhere
|
||||
may be a good idea as well.
|
||||
.SH NOTES ON RANDOM NUMBER GENERATORS
|
||||
Random Number Generators (RNG) used in cryptsetup are always the
|
||||
kernel RNGs without any modifications or additions to data stream
|
||||
produced.
|
||||
|
||||
There are two types of randomness cryptsetup/LUKS needs. One type
|
||||
(which always uses /dev/urandom) is used for salts, the AF splitter
|
||||
and for wiping deleted keyslots.
|
||||
|
||||
The second type is used for the volume (master) key. You can switch
|
||||
between using /dev/random and /dev/urandom here, see
|
||||
\fP\-\-use-random\fR and \fP\-\-use-urandom\fR
|
||||
options. Using /dev/random on a system without enough entropy sources
|
||||
can cause \fPluksFormat\fR to block until the requested amount of
|
||||
random data is gathered. In a low-entropy situation (embedded system),
|
||||
this can take a very long time and potentially forever. At the same
|
||||
time, using /dev/urandom in a low-entropy situation will
|
||||
produce low-quality keys. This is a serious problem, but solving
|
||||
it is out of scope for a mere man-page.
|
||||
See \fPurandom(4)\fR for more information.
|
||||
.SH NOTES ON LOOPBACK DEVICE USE
|
||||
Cryptsetup is usually used directly on a block device (disk
|
||||
partition or LVM volume). However, if the device argument is a
|
||||
file, cryptsetup tries to allocate a loopback device
|
||||
and map it into this file. This mode requires Linux kernel 2.6.25
|
||||
or more recent which supports the loop autoclear flag (loop device is
|
||||
cleared on last close automatically). Of course, you can
|
||||
always map a file to a loop-device manually. See the
|
||||
cryptsetup FAQ for an example.
|
||||
|
||||
When device mapping is active, you can see the loop backing file in
|
||||
the status command output. Also see losetup(8).
|
||||
.SH DEPRECATED ACTIONS
|
||||
.PP
|
||||
\fIreload\fR <name> <device>
|
||||
.IP
|
||||
modifies an active mapping <name>. Same options as for
|
||||
create.
|
||||
.B WARNING:
|
||||
Do not use this for LUKS devices, as the semantics
|
||||
are identical to the create action, which are totally incompatible
|
||||
with the LUKS key setup.
|
||||
|
||||
This action is deprected because it proved to be rarely useful. It is
|
||||
uncommon to change the underlying device, key, or offset on the
|
||||
fly. In case, you really want to do this, you certainly know what you
|
||||
are doing and then you are probably better off with the swiss knive
|
||||
tool for device mapper, namely dmsetup. It provides you with the same
|
||||
functionality, see dmsetup reload.
|
||||
The \fIreload\fR action is no longer supported.
|
||||
Please use \fIdmsetup(8)\fR if you need to
|
||||
directly manipulate with the device mapping table.
|
||||
.PP
|
||||
\fIluksDelKey\fR <device> <key slot number>
|
||||
.IP
|
||||
identical to luksKillSlot, but deprecated action name. This option was
|
||||
renamed, as we introduced luksRemoveKey, a softer method for disabling
|
||||
password slots. To make a clear distinction that luksDelKey was more brutal than luksRemoveKey
|
||||
|
||||
|
||||
.SH "REPORTING BUGS"
|
||||
Report bugs to <dm-crypt@saout.de>.
|
||||
The \fIluksDelKey\fR was replaced with \fIluksKillSlot\fR.
|
||||
.PP
|
||||
.SH REPORTING BUGS
|
||||
Report bugs, including ones in the documentation, on
|
||||
the cryptsetup mailing list at <dm-crypt@saout.de>
|
||||
or in the 'Issues' section on LUKS website.
|
||||
Please attach the output of the failed command with the
|
||||
\-\-debug option added.
|
||||
.SH AUTHORS
|
||||
cryptsetup originally written by Christophe Saout <christophe@saout.de>
|
||||
.br
|
||||
The LUKS extensions and original man page were written by
|
||||
Clemens Fruhwirth <clemens@endorphin.org>.
|
||||
.br
|
||||
Man page extensions by Milan Broz <gmazyland@gmail.com>.
|
||||
.br
|
||||
Man page rewrite and extension by Arno Wagner <arno@wagner.name>.
|
||||
.SH COPYRIGHT
|
||||
Copyright \(co 2004 Christophe Saout
|
||||
.br
|
||||
Copyright \(co 2004-2006 Clemens Fruhwirth
|
||||
.br
|
||||
Copyright \(co 2009-2012 Red Hat, Inc.
|
||||
.br
|
||||
Copyright \(co 2012 Arno Wagner
|
||||
|
||||
This is free software; see the source for copying conditions. There is NO
|
||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
.SH "SEE ALSO"
|
||||
.SH SEE ALSO
|
||||
The LUKS website at \fBhttp://code.google.com/p/cryptsetup/\fR
|
||||
|
||||
dm-crypt website, \fBhttp://www.saout.de/misc/dm-crypt/\fR
|
||||
The cryptsetup FAQ, contained in the distribution package and
|
||||
online at
|
||||
\fBhttp://code.google.com/p/cryptsetup/wiki/FrequentlyAskedQuestions\fR
|
||||
|
||||
LUKS website, \fBhttp://code.google.com/p/cryptsetup/\fR
|
||||
The cryptsetup mailing list and list archive, see FAQ entry 1.6.
|
||||
|
||||
dm-crypt TWiki, \fBhttp://www.saout.de/tikiwiki/tiki-index.php\fR
|
||||
The LUKS on-disk format specification available at
|
||||
\fBhttp://code.google.com/p/cryptsetup/wiki/Specification\fR
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user