Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 36882
Collapse All | Expand All

(-)util-linux-2.12/mount/Makefile (-7 / +15 lines)
Lines 24-30 Link Here
24
24
25
MAYBE = pivot_root swapoff
25
MAYBE = pivot_root swapoff
26
26
27
LO_OBJS = lomount.o $(LIB)/xstrncpy.o
28
NFS_OBJS = nfsmount.o nfsmount_xdr.o nfsmount_clnt.o
27
NFS_OBJS = nfsmount.o nfsmount_xdr.o nfsmount_clnt.o
29
GEN_FILES = nfsmount.h nfsmount_xdr.c nfsmount_clnt.c
28
GEN_FILES = nfsmount.h nfsmount_xdr.c nfsmount_clnt.c
30
29
Lines 44-65 Link Here
44
43
45
mount: mount.o fstab.o sundries.o realpath.o mntent.o version.o \
44
mount: mount.o fstab.o sundries.o realpath.o mntent.o version.o \
46
       mount_guess_fstype.o get_label_uuid.o mount_by_label.o getusername.o \
45
       mount_guess_fstype.o get_label_uuid.o mount_by_label.o getusername.o \
47
       $(LIB)/setproctitle.o $(LIB)/env.o $(NFS_OBJS) $(LO_OBJS)
46
       $(LIB)/setproctitle.o $(LIB)/env.o $(NFS_OBJS) lomount.o loumount.o \
47
       loop.o sha512.o rmd160.o aes.o $(LIB)/xstrncpy.o
48
	$(LINK) $^ -o $@
48
	$(LINK) $^ -o $@
49
49
50
umount: umount.o fstab.o sundries.o realpath.o mntent.o getusername.o \
50
umount: umount.o fstab.o sundries.o realpath.o mntent.o getusername.o \
51
	get_label_uuid.o version.o $(LIB)/env.o $(LO_OBJS)
51
	get_label_uuid.o version.o $(LIB)/env.o loumount.o
52
	$(LINK) $^ -o $@
52
	$(LINK) $^ -o $@
53
53
54
swapon:	swapon.o version.o
54
swapon:	swapon.o version.o loop.o sha512.o $(LIB)/xstrncpy.o
55
	$(LINK) $^ -o $@
55
	$(LINK) $^ -o $@
56
56
57
main_losetup.o: lomount.c
57
main_losetup.o: lomount.c
58
	$(COMPILE) -DMAIN lomount.c -o $@
58
	$(COMPILE) -DMAIN lomount.c -o $@
59
59
60
losetup: main_losetup.o $(LIB)/xstrncpy.o
60
losetup: main_losetup.o loumount.o loop.o sha512.o rmd160.o aes.o $(LIB)/xstrncpy.o
61
	$(LINK) $^ -o $@
61
	$(LINK) $^ -o $@
62
62
63
loop.o lomount.o main_losetup.o swapon.o: loop.h
64
65
sha512.o lomount.o main_losetup.o swapon.o: sha512.h
66
67
rmd160.o lomount.o main_losetup.o: rmd160.h
68
69
aes.o lomount.o main_losetup.o: aes.h
70
63
mount.o umount.o nfsmount.o losetup.o fstab.o realpath.o sundries.o: sundries.h
71
mount.o umount.o nfsmount.o losetup.o fstab.o realpath.o sundries.o: sundries.h
64
72
65
mount.o umount.o fstab.o sundries.o: fstab.h
73
mount.o umount.o fstab.o sundries.o: fstab.h
Lines 72-80 Link Here
72
80
73
mount.o umount.o getusername.o: getusername.h
81
mount.o umount.o getusername.o: getusername.h
74
82
75
mount.o umount.o losetup.o lomount.o: lomount.h loop.h my_dev_t.h
83
mount.o umount.o losetup.o lomount.o loumount.o: lomount.h loop.h
76
84
77
swapon.o: swap_constants.h swapargs.h
85
swapon.o: swap_constants.h swapargs.h loop.h
78
86
79
sundries.o nfsmount.o nfsmount_xdr.o nfsmount_clnt.o: nfsmount.h
87
sundries.o nfsmount.o nfsmount_xdr.o nfsmount_clnt.o: nfsmount.h
80
88
(-)util-linux-2.12/mount/aes.c (+299 lines)
Line 0 Link Here
1
// I retain copyright in this code but I encourage its free use provided
2
// that I don't carry any responsibility for the results. I am especially 
3
// happy to see it used in free and open source software. If you do use 
4
// it I would appreciate an acknowledgement of its origin in the code or
5
// the product that results and I would also appreciate knowing a little
6
// about the use to which it is being put. I am grateful to Frank Yellin
7
// for some ideas that are used in this implementation.
8
//
9
// Dr B. R. Gladman <brg@gladman.uk.net> 6th April 2001.
10
//
11
// This is an implementation of the AES encryption algorithm (Rijndael)
12
// designed by Joan Daemen and Vincent Rijmen. This version is designed
13
// to provide both fixed and dynamic block and key lengths and can also 
14
// run with either big or little endian internal byte order (see aes.h). 
15
// It inputs block and key lengths in bytes with the legal values being 
16
// 16, 24 and 32.
17
18
/*
19
 * Modified by Jari Ruusu,  May 1 2001
20
 *  - Fixed some compile warnings, code was ok but gcc warned anyway.
21
 *  - Changed basic types: byte -> unsigned char, word -> u_int32_t
22
 *  - Major name space cleanup: Names visible to outside now begin
23
 *    with "aes_" or "AES_". A lot of stuff moved from aes.h to aes.c
24
 *  - Removed C++ and DLL support as part of name space cleanup.
25
 *  - Eliminated unnecessary recomputation of tables. (actual bug fix)
26
 *  - Merged precomputed constant tables to aes.c file.
27
 *  - Removed data alignment restrictions for portability reasons.
28
 *  - Made block and key lengths accept bit count (128/192/256)
29
 *    as well byte count (16/24/32).
30
 *  - Removed all error checks. This change also eliminated the need
31
 *    to preinitialize the context struct to zero.
32
 *  - Removed some totally unused constants.
33
 */
34
35
/*
36
 * Modified by Jari Ruusu,  June 9 2003
37
 *  - Removed all code not necessary for small size
38
 *    optimized encryption using 256 bit keys.
39
 */
40
41
#include "aes.h"
42
43
#if AES_BLOCK_SIZE != 16
44
#error an illegal block size has been specified
45
#endif  
46
47
// upr(x,n): rotates bytes within words by n positions, moving bytes 
48
// to higher index positions with wrap around into low positions
49
// bval(x,n): extracts a byte from a word
50
51
#define upr(x,n)        (((x) << 8 * (n)) | ((x) >> (32 - 8 * (n))))
52
#define bval(x,n)       ((unsigned char)((x) >> 8 * (n)))
53
#define bytes2word(b0, b1, b2, b3)  \
54
        ((u_int32_t)(b3) << 24 | (u_int32_t)(b2) << 16 | (u_int32_t)(b1) << 8 | (b0))
55
56
#if defined(i386) || defined(_I386) || defined(__i386__) || defined(__i386)
57
/* little endian processor without data alignment restrictions */
58
#define word_in(x)      *(u_int32_t*)(x)
59
#define word_out(x,v)   *(u_int32_t*)(x) = (v)
60
#else
61
/* slower but generic big endian or with data alignment restrictions */
62
#define word_in(x)      ((u_int32_t)(((unsigned char *)(x))[0])|((u_int32_t)(((unsigned char *)(x))[1])<<8)|((u_int32_t)(((unsigned char *)(x))[2])<<16)|((u_int32_t)(((unsigned char *)(x))[3])<<24))
63
#define word_out(x,v)   ((unsigned char *)(x))[0]=(v),((unsigned char *)(x))[1]=((v)>>8),((unsigned char *)(x))[2]=((v)>>16),((unsigned char *)(x))[3]=((v)>>24)
64
#endif
65
66
// the finite field modular polynomial and elements
67
68
#define ff_poly 0x011b
69
#define ff_hi   0x80
70
71
static int tab_gen = 0;
72
static unsigned char  s_box[256];            // the S box
73
static u_int32_t  rcon_tab[AES_RC_LENGTH];   // table of round constants
74
static u_int32_t  ft_tab[4][256];
75
static u_int32_t  fl_tab[4][256];
76
77
// Generate the tables for the dynamic table option
78
79
// It will generally be sensible to use tables to compute finite 
80
// field multiplies and inverses but where memory is scarse this 
81
// code might sometimes be better.
82
83
// return 2 ^ (n - 1) where n is the bit number of the highest bit
84
// set in x with x in the range 1 < x < 0x00000200.   This form is
85
// used so that locals within FFinv can be bytes rather than words
86
87
static unsigned char hibit(const u_int32_t x)
88
{   unsigned char r = (unsigned char)((x >> 1) | (x >> 2));
89
    
90
    r |= (r >> 2);
91
    r |= (r >> 4);
92
    return (r + 1) >> 1;
93
}
94
95
// return the inverse of the finite field element x
96
97
static unsigned char FFinv(const unsigned char x)
98
{   unsigned char    p1 = x, p2 = 0x1b, n1 = hibit(x), n2 = 0x80, v1 = 1, v2 = 0;
99
100
    if(x < 2) return x;
101
102
    for(;;)
103
    {
104
        if(!n1) return v1;
105
106
        while(n2 >= n1)
107
        {   
108
            n2 /= n1; p2 ^= p1 * n2; v2 ^= v1 * n2; n2 = hibit(p2);
109
        }
110
        
111
        if(!n2) return v2;
112
113
        while(n1 >= n2)
114
        {   
115
            n1 /= n2; p1 ^= p2 * n1; v1 ^= v2 * n1; n1 = hibit(p1);
116
        }
117
    }
118
}
119
120
// define the finite field multiplies required for Rijndael
121
122
#define FFmul02(x)  ((((x) & 0x7f) << 1) ^ ((x) & 0x80 ? 0x1b : 0))
123
#define FFmul03(x)  ((x) ^ FFmul02(x))
124
125
// The forward and inverse affine transformations used in the S-box
126
127
#define fwd_affine(x) \
128
    (w = (u_int32_t)x, w ^= (w<<1)^(w<<2)^(w<<3)^(w<<4), 0x63^(unsigned char)(w^(w>>8)))
129
130
static void gen_tabs(void)
131
{   u_int32_t  i, w;
132
133
    for(i = 0, w = 1; i < AES_RC_LENGTH; ++i)
134
    {
135
        rcon_tab[i] = bytes2word(w, 0, 0, 0);
136
        w = (w << 1) ^ (w & ff_hi ? ff_poly : 0);
137
    }
138
139
    for(i = 0; i < 256; ++i)
140
    {   unsigned char    b;
141
142
        s_box[i] = b = fwd_affine(FFinv((unsigned char)i));
143
144
        w = bytes2word(b, 0, 0, 0);
145
        fl_tab[0][i] = w;
146
        fl_tab[1][i] = upr(w,1);
147
        fl_tab[2][i] = upr(w,2);
148
        fl_tab[3][i] = upr(w,3);
149
        w = bytes2word(FFmul02(b), b, b, FFmul03(b));
150
        ft_tab[0][i] = w;
151
        ft_tab[1][i] = upr(w,1);
152
        ft_tab[2][i] = upr(w,2);
153
        ft_tab[3][i] = upr(w,3);
154
    }
155
}
156
157
#define four_tables(x,tab,vf,rf,c) \
158
 (  tab[0][bval(vf(x,0,c),rf(0,c))] \
159
  ^ tab[1][bval(vf(x,1,c),rf(1,c))] \
160
  ^ tab[2][bval(vf(x,2,c),rf(2,c))] \
161
  ^ tab[3][bval(vf(x,3,c),rf(3,c))])
162
163
#define vf1(x,r,c)  (x)
164
#define rf1(r,c)    (r)
165
#define rf2(r,c)    ((r-c)&3)
166
167
#define ls_box(x,c)     four_tables(x,fl_tab,vf1,rf2,c)
168
169
#define nc   (AES_BLOCK_SIZE / 4)
170
171
// Initialise the key schedule from the user supplied key.
172
// The key length is now specified in bytes, 32.
173
// This corresponds to bit length of 256 bits, and
174
// to Nk value of 8 respectively.
175
176
void aes_set_key(aes_context *cx, const unsigned char in_key[], int n_bytes, const int f)
177
{   u_int32_t    *kf, *kt, rci;
178
179
    if(!tab_gen) { gen_tabs(); tab_gen = 1; }
180
181
    cx->aes_Nkey = 8;
182
    cx->aes_Nrnd = (cx->aes_Nkey > nc ? cx->aes_Nkey : nc) + 6; 
183
184
    cx->aes_e_key[0] = word_in(in_key     );
185
    cx->aes_e_key[1] = word_in(in_key +  4);
186
    cx->aes_e_key[2] = word_in(in_key +  8);
187
    cx->aes_e_key[3] = word_in(in_key + 12);
188
189
    kf = cx->aes_e_key; 
190
    kt = kf + nc * (cx->aes_Nrnd + 1) - cx->aes_Nkey; 
191
    rci = 0;
192
193
    switch(cx->aes_Nkey)
194
    {
195
    case 8: cx->aes_e_key[4] = word_in(in_key + 16);
196
            cx->aes_e_key[5] = word_in(in_key + 20);
197
            cx->aes_e_key[6] = word_in(in_key + 24);
198
            cx->aes_e_key[7] = word_in(in_key + 28);
199
            do
200
            {   kf[ 8] = kf[0] ^ ls_box(kf[7],3) ^ rcon_tab[rci++];
201
                kf[ 9] = kf[1] ^ kf[ 8];
202
                kf[10] = kf[2] ^ kf[ 9];
203
                kf[11] = kf[3] ^ kf[10];
204
                kf[12] = kf[4] ^ ls_box(kf[11],0);
205
                kf[13] = kf[5] ^ kf[12];
206
                kf[14] = kf[6] ^ kf[13];
207
                kf[15] = kf[7] ^ kf[14];
208
                kf += 8;
209
            }
210
            while (kf < kt);
211
            break;
212
    }
213
}
214
215
// y = output word, x = input word, r = row, c = column
216
// for r = 0, 1, 2 and 3 = column accessed for row r
217
218
#define s(x,c) x[c]
219
220
// I am grateful to Frank Yellin for the following constructions
221
// which, given the column (c) of the output state variable that
222
// is being computed, return the input state variables which are
223
// needed for each row (r) of the state
224
225
// For the fixed block size options, compilers reduce these two 
226
// expressions to fixed variable references. For variable block 
227
// size code conditional clauses will sometimes be returned
228
229
#define fwd_var(x,r,c) \
230
 ( r==0 ?			\
231
    ( c==0 ? s(x,0) \
232
    : c==1 ? s(x,1) \
233
    : c==2 ? s(x,2) \
234
    : c==3 ? s(x,3) \
235
    : c==4 ? s(x,4) \
236
    : c==5 ? s(x,5) \
237
    : c==6 ? s(x,6) \
238
    : s(x,7))		\
239
 : r==1 ?			\
240
    ( c==0 ? s(x,1) \
241
    : c==1 ? s(x,2) \
242
    : c==2 ? s(x,3) \
243
    : c==3 ? nc==4 ? s(x,0) : s(x,4) \
244
    : c==4 ? s(x,5) \
245
    : c==5 ? nc==8 ? s(x,6) : s(x,0) \
246
    : c==6 ? s(x,7) \
247
    : s(x,0))		\
248
 : r==2 ?			\
249
    ( c==0 ? nc==8 ? s(x,3) : s(x,2) \
250
    : c==1 ? nc==8 ? s(x,4) : s(x,3) \
251
    : c==2 ? nc==4 ? s(x,0) : nc==8 ? s(x,5) : s(x,4) \
252
    : c==3 ? nc==4 ? s(x,1) : nc==8 ? s(x,6) : s(x,5) \
253
    : c==4 ? nc==8 ? s(x,7) : s(x,0) \
254
    : c==5 ? nc==8 ? s(x,0) : s(x,1) \
255
    : c==6 ? s(x,1) \
256
    : s(x,2))		\
257
 :					\
258
    ( c==0 ? nc==8 ? s(x,4) : s(x,3) \
259
    : c==1 ? nc==4 ? s(x,0) : nc==8 ? s(x,5) : s(x,4) \
260
    : c==2 ? nc==4 ? s(x,1) : nc==8 ? s(x,6) : s(x,5) \
261
    : c==3 ? nc==4 ? s(x,2) : nc==8 ? s(x,7) : s(x,0) \
262
    : c==4 ? nc==8 ? s(x,0) : s(x,1) \
263
    : c==5 ? nc==8 ? s(x,1) : s(x,2) \
264
    : c==6 ? s(x,2) \
265
    : s(x,3)))
266
267
#define si(y,x,k,c) s(y,c) = word_in(x + 4 * c) ^ k[c]
268
#define so(y,x,c)   word_out(y + 4 * c, s(x,c))
269
270
#define fwd_rnd(y,x,k,c)    s(y,c)= (k)[c] ^ four_tables(x,ft_tab,fwd_var,rf1,c)
271
#define fwd_lrnd(y,x,k,c)   s(y,c)= (k)[c] ^ four_tables(x,fl_tab,fwd_var,rf1,c)
272
273
#define locals(y,x)     x[4],y[4]
274
275
#define l_copy(y, x)    s(y,0) = s(x,0); s(y,1) = s(x,1); \
276
                        s(y,2) = s(x,2); s(y,3) = s(x,3);
277
#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); si(y,x,k,3)
278
#define state_out(y,x)  so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3)
279
#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); rm(y,x,k,3)
280
281
void aes_encrypt(const aes_context *cx, const unsigned char in_blk[], unsigned char out_blk[])
282
{   u_int32_t        locals(b0, b1);
283
    const u_int32_t  *kp = cx->aes_e_key;
284
285
    state_in(b0, in_blk, kp); kp += nc;
286
287
    {   u_int32_t    rnd;
288
289
        for(rnd = 0; rnd < cx->aes_Nrnd - 1; ++rnd)
290
        {
291
            round(fwd_rnd, b1, b0, kp); 
292
            l_copy(b0, b1); kp += nc;
293
        }
294
295
        round(fwd_lrnd, b0, b1, kp);
296
    }
297
298
    state_out(out_blk, b0);
299
}
(-)util-linux-2.12/mount/aes.h (+97 lines)
Line 0 Link Here
1
// I retain copyright in this code but I encourage its free use provided
2
// that I don't carry any responsibility for the results. I am especially 
3
// happy to see it used in free and open source software. If you do use 
4
// it I would appreciate an acknowledgement of its origin in the code or
5
// the product that results and I would also appreciate knowing a little
6
// about the use to which it is being put. I am grateful to Frank Yellin
7
// for some ideas that are used in this implementation.
8
//
9
// Dr B. R. Gladman <brg@gladman.uk.net> 6th April 2001.
10
//
11
// This is an implementation of the AES encryption algorithm (Rijndael)
12
// designed by Joan Daemen and Vincent Rijmen. This version is designed
13
// to provide both fixed and dynamic block and key lengths and can also 
14
// run with either big or little endian internal byte order (see aes.h). 
15
// It inputs block and key lengths in bytes with the legal values being 
16
// 16, 24 and 32.
17
18
/*
19
 * Modified by Jari Ruusu,  May 1 2001
20
 *  - Fixed some compile warnings, code was ok but gcc warned anyway.
21
 *  - Changed basic types: byte -> unsigned char, word -> u_int32_t
22
 *  - Major name space cleanup: Names visible to outside now begin
23
 *    with "aes_" or "AES_". A lot of stuff moved from aes.h to aes.c
24
 *  - Removed C++ and DLL support as part of name space cleanup.
25
 *  - Eliminated unnecessary recomputation of tables. (actual bug fix)
26
 *  - Merged precomputed constant tables to aes.c file.
27
 *  - Removed data alignment restrictions for portability reasons.
28
 *  - Made block and key lengths accept bit count (128/192/256)
29
 *    as well byte count (16/24/32).
30
 *  - Removed all error checks. This change also eliminated the need
31
 *    to preinitialize the context struct to zero.
32
 *  - Removed some totally unused constants.
33
 */
34
35
#ifndef _AES_H
36
#define _AES_H
37
38
#if defined(__linux__) && defined(__KERNEL__)
39
#  include <linux/types.h>
40
#else 
41
#  include <sys/types.h>
42
#endif
43
44
// CONFIGURATION OPTIONS (see also aes.c)
45
//
46
// Define AES_BLOCK_SIZE to set the cipher block size (16, 24 or 32) or
47
// leave this undefined for dynamically variable block size (this will
48
// result in much slower code).
49
// IMPORTANT NOTE: AES_BLOCK_SIZE is in BYTES (16, 24, 32 or undefined). If
50
// left undefined a slower version providing variable block length is compiled
51
52
#define AES_BLOCK_SIZE  16
53
54
// The number of key schedule words for different block and key lengths
55
// allowing for method of computation which requires the length to be a
56
// multiple of the key length
57
//
58
// Nk =       4   6   8
59
//        -------------
60
// Nb = 4 |  60  60  64
61
//      6 |  96  90  96
62
//      8 | 120 120 120
63
64
#if !defined(AES_BLOCK_SIZE) || (AES_BLOCK_SIZE == 32)
65
#define AES_KS_LENGTH   120
66
#define AES_RC_LENGTH    29
67
#else
68
#define AES_KS_LENGTH   4 * AES_BLOCK_SIZE
69
#define AES_RC_LENGTH   (9 * AES_BLOCK_SIZE) / 8 - 8
70
#endif
71
72
typedef struct
73
{
74
    u_int32_t    aes_Nkey;      // the number of words in the key input block
75
    u_int32_t    aes_Nrnd;      // the number of cipher rounds
76
    u_int32_t    aes_e_key[AES_KS_LENGTH];   // the encryption key schedule
77
    u_int32_t    aes_d_key[AES_KS_LENGTH];   // the decryption key schedule
78
#if !defined(AES_BLOCK_SIZE)
79
    u_int32_t    aes_Ncol;      // the number of columns in the cipher state
80
#endif
81
} aes_context;
82
83
// THE CIPHER INTERFACE
84
85
#if !defined(AES_BLOCK_SIZE)
86
extern void aes_set_blk(aes_context *, const int);
87
#endif
88
extern void aes_set_key(aes_context *, const unsigned char [], const int, const int);
89
extern void aes_encrypt(const aes_context *, const unsigned char [], unsigned char []);
90
extern void aes_decrypt(const aes_context *, const unsigned char [], unsigned char []);
91
92
// The block length inputs to aes_set_block and aes_set_key are in numbers
93
// of bytes or bits.  The calls to subroutines must be made in the above
94
// order but multiple calls can be made without repeating earlier calls
95
// if their parameters have not changed.
96
97
#endif  // _AES_H
(-)util-linux-2.12/mount/lomount.c (-280 / +757 lines)
Lines 7-16 Link Here
7
 * - added Native Language Support
7
 * - added Native Language Support
8
 * 1999-03-21 Arnaldo Carvalho de Melo <acme@conectiva.com.br>
8
 * 1999-03-21 Arnaldo Carvalho de Melo <acme@conectiva.com.br>
9
 * - fixed strerr(errno) in gettext calls
9
 * - fixed strerr(errno) in gettext calls
10
 * 2000-09-24 Marc Mutz <Marc@Mutz.com>
10
 * 2001-04-11 Jari Ruusu
11
 * - added -p option to pass passphrases via fd's to losetup/mount.
11
 * - added AES support
12
 *   Used for encryption in non-interactive environments.
13
 *   The idea behind xgetpass() is stolen from GnuPG, v.1.0.3.
14
 */
12
 */
15
13
16
#define LOOPMAJOR	7
14
#define LOOPMAJOR	7
Lines 26-84 Link Here
26
#include <errno.h>
24
#include <errno.h>
27
#include <stdlib.h>
25
#include <stdlib.h>
28
#include <unistd.h>
26
#include <unistd.h>
27
#include <pwd.h>
28
#include <sys/types.h>
29
#include <sys/ioctl.h>
29
#include <sys/ioctl.h>
30
#include <sys/stat.h>
30
#include <sys/stat.h>
31
#include <sys/mman.h>
31
#include <sys/mman.h>
32
#include <sys/sysmacros.h>
32
#include <sys/sysmacros.h>
33
#include <sys/wait.h>
34
#include <limits.h>
35
#include <fcntl.h>
36
#include <mntent.h>
37
#include <locale.h>
38
#include <sys/utsname.h>
33
39
34
#include "loop.h"
40
#include "loop.h"
35
#include "lomount.h"
41
#include "lomount.h"
36
#include "xstrncpy.h"
42
#include "xstrncpy.h"
37
#include "nls.h"
43
#include "nls.h"
44
#include "sha512.h"
45
#include "rmd160.h"
46
#include "aes.h"
38
47
39
extern int verbose;
48
extern int verbose;
40
extern char *xstrdup (const char *s);	/* not: #include "sundries.h" */
49
extern char *xstrdup (const char *s);	/* not: #include "sundries.h" */
41
extern void error (const char *fmt, ...);	/* idem */
50
extern void error (const char *fmt, ...);	/* idem */
51
extern void show_all_loops(void);
52
extern int read_options_from_fstab(char *, char **);
42
53
43
#ifdef LOOP_SET_FD
54
#if !defined(LOOP_PASSWORD_MIN_LENGTH)
44
55
# define  LOOP_PASSWORD_MIN_LENGTH   20
45
static int
56
#endif
46
loop_info64_to_old(const struct loop_info64 *info64, struct loop_info *info)
47
{
48
        memset(info, 0, sizeof(*info));
49
        info->lo_number = info64->lo_number;
50
        info->lo_device = info64->lo_device;
51
        info->lo_inode = info64->lo_inode;
52
        info->lo_rdevice = info64->lo_rdevice;
53
        info->lo_offset = info64->lo_offset;
54
        info->lo_encrypt_type = info64->lo_encrypt_type;
55
        info->lo_encrypt_key_size = info64->lo_encrypt_key_size;
56
        info->lo_flags = info64->lo_flags;
57
        info->lo_init[0] = info64->lo_init[0];
58
        info->lo_init[1] = info64->lo_init[1];
59
        if (info->lo_encrypt_type == LO_CRYPT_CRYPTOAPI)
60
                memcpy(info->lo_name, info64->lo_crypt_name, LO_NAME_SIZE);
61
        else
62
                memcpy(info->lo_name, info64->lo_file_name, LO_NAME_SIZE);
63
        memcpy(info->lo_encrypt_key, info64->lo_encrypt_key, LO_KEY_SIZE);
64
65
        /* error in case values were truncated */
66
        if (info->lo_device != info64->lo_device ||
67
            info->lo_rdevice != info64->lo_rdevice ||
68
            info->lo_inode != info64->lo_inode ||
69
            info->lo_offset != info64->lo_offset)
70
                return -EOVERFLOW;
71
57
72
        return 0;
58
char    *passFDnumber = (char *)0;
73
}
59
char    *passAskTwice = (char *)0;
60
char    *passSeedString = (char *)0;
61
char    *passHashFuncName = (char *)0;
62
char    *passIterThousands = (char *)0;
63
char    *loInitValue = (char *)0;
64
char    *gpgKeyFile = (char *)0;
65
char    *gpgHomeDir = (char *)0;
66
char    *loopOffsetBytes = (char *)0;
67
char    *loopSizeBytes = (char *)0;
68
char    *loopEncryptionType = (char *)0;
69
70
static int  multiKeyMode = 0;
71
static char *multiKeyPass[64];
72
static char *loopFileName;
74
73
75
#ifdef MAIN
74
#ifdef MAIN
75
static char *
76
crypt_name (int id, int *flags) {
77
	int i;
78
79
	for (i = 0; loop_crypt_type_tbl[i].id != -1; i++)
80
		if(id == loop_crypt_type_tbl[i].id) {
81
			*flags = loop_crypt_type_tbl[i].flags;
82
			return loop_crypt_type_tbl[i].name;
83
		}
84
	*flags = 0;
85
	if(id == 18)
86
		return "CryptoAPI";
87
	return "undefined";
88
}
76
89
77
static int
90
static int
78
show_loop(char *device) {
91
show_loop(char *device) {
79
	struct loop_info loopinfo;
92
	struct loop_info64 loopinfo;
80
	struct loop_info64 loopinfo64;
93
	int fd;
81
	int fd, errsv;
82
94
83
	if ((fd = open(device, O_RDONLY)) < 0) {
95
	if ((fd = open(device, O_RDONLY)) < 0) {
84
		int errsv = errno;
96
		int errsv = errno;
Lines 86-155 Link Here
86
			device, strerror (errsv));
98
			device, strerror (errsv));
87
		return 2;
99
		return 2;
88
	}
100
	}
89
101
	if (loop_get_status64_ioctl(fd, &loopinfo) < 0) {
90
	if (ioctl(fd, LOOP_GET_STATUS64, &loopinfo64) == 0) {
102
		int errsv = errno;
91
103
		fprintf(stderr, _("loop: can't get info on device %s: %s\n"),
92
		loopinfo64.lo_file_name[LO_NAME_SIZE-2] = '*';
104
			device, strerror (errsv));
93
		loopinfo64.lo_file_name[LO_NAME_SIZE-1] = 0;
94
		loopinfo64.lo_crypt_name[LO_NAME_SIZE-1] = 0;
95
96
		printf("%s: [%04llx]:%llu (%s)",
97
		       device, loopinfo64.lo_device, loopinfo64.lo_inode,
98
		       loopinfo64.lo_file_name);
99
100
		if (loopinfo64.lo_offset)
101
			printf(_(", offset %lld"), loopinfo64.lo_offset);
102
103
		if (loopinfo64.lo_sizelimit)
104
			printf(_(", sizelimit %lld"), loopinfo64.lo_sizelimit);
105
106
		if (loopinfo64.lo_encrypt_type ||
107
		    loopinfo64.lo_crypt_name[0]) {
108
			char *e = loopinfo64.lo_crypt_name;
109
110
			if (*e == 0 && loopinfo64.lo_encrypt_type == 1)
111
				e = "XOR";
112
			printf(_(", encryption %s (type %d)"),
113
			       e, loopinfo64.lo_encrypt_type);
114
		}
115
		printf("\n");
116
		close (fd);
105
		close (fd);
117
		return 0;
106
		return 1;
118
	}
107
	}
119
108
	loopinfo.lo_file_name[LO_NAME_SIZE-1] = 0;
120
	if (ioctl(fd, LOOP_GET_STATUS, &loopinfo) == 0) {
109
	loopinfo.lo_crypt_name[LO_NAME_SIZE-1] = 0;
121
		printf ("%s: [%04x]:%ld (%s)",
110
	printf("%s: [%04llx]:%llu (%s)", device, (unsigned long long)loopinfo.lo_device,
122
			device, loopinfo.lo_device, loopinfo.lo_inode,
111
		(unsigned long long)loopinfo.lo_inode, loopinfo.lo_file_name);
123
			loopinfo.lo_name);
112
	if (loopinfo.lo_offset) {
124
113
		if ((long long)loopinfo.lo_offset < 0) {
125
		if (loopinfo.lo_offset)
114
			printf(_(" offset=@%llu"), -((unsigned long long)loopinfo.lo_offset));
126
			printf(_(", offset %d"), loopinfo.lo_offset);
115
		} else {
127
116
			printf(_(" offset=%llu"), (unsigned long long)loopinfo.lo_offset);
128
		if (loopinfo.lo_encrypt_type)
117
		}
129
			printf(_(", encryption type %d\n"),
130
			       loopinfo.lo_encrypt_type);
131
132
		printf("\n");
133
		close (fd);
134
		return 0;
135
	}
118
	}
136
119
	if (loopinfo.lo_sizelimit)
137
	errsv = errno;
120
		printf(_(" sizelimit=%llu"), (unsigned long long)loopinfo.lo_sizelimit);
138
	fprintf(stderr, _("loop: can't get info on device %s: %s\n"),
121
	if (loopinfo.lo_encrypt_type) {
139
		device, strerror (errsv));
122
		int flags;
123
		unsigned char *s = crypt_name (loopinfo.lo_encrypt_type, &flags);
124
125
		printf(_(" encryption=%s"), s);
126
		/* type 18 == LO_CRYPT_CRYPTOAPI */
127
		if (loopinfo.lo_encrypt_type == 18) {
128
			printf("/%s", loopinfo.lo_crypt_name);
129
		} else {
130
			if(flags & 2)
131
				printf("-");
132
			if(flags & 1)
133
				printf("%u", (unsigned int)loopinfo.lo_encrypt_key_size << 3);
134
		}
135
	}
136
	if (loopinfo.lo_flags & 0x100000)
137
		printf(_(" multi-key"));
138
	/* type 2 == LO_CRYPT_DES */
139
	if (loopinfo.lo_init[0] && (loopinfo.lo_encrypt_type != 2))
140
		printf(_(" loinit=%llu"), (unsigned long long)loopinfo.lo_init[0]);
141
	if (loopinfo.lo_flags & 0x200000)
142
		printf(_(" read-only"));
143
	printf("\n");
140
	close (fd);
144
	close (fd);
141
	return 1;
142
}
143
#endif
144
145
int
146
is_loop_device (const char *device) {
147
	struct stat statbuf;
148
145
149
	return (stat(device, &statbuf) == 0 &&
146
	return 0;
150
		S_ISBLK(statbuf.st_mode) &&
151
		major(statbuf.st_rdev) == LOOPMAJOR);
152
}
147
}
148
#endif
153
149
154
#define SIZE(a) (sizeof(a)/sizeof(a[0]))
150
#define SIZE(a) (sizeof(a)/sizeof(a[0]))
155
151
Lines 162-168 Link Here
162
	char *loop_formats[] = { "/dev/loop%d", "/dev/loop/%d" };
158
	char *loop_formats[] = { "/dev/loop%d", "/dev/loop/%d" };
163
	int i, j, fd, somedev = 0, someloop = 0;
159
	int i, j, fd, somedev = 0, someloop = 0;
164
	struct stat statbuf;
160
	struct stat statbuf;
165
	struct loop_info loopinfo;
166
161
167
	for (j = 0; j < SIZE(loop_formats); j++) {
162
	for (j = 0; j < SIZE(loop_formats); j++) {
168
	    for(i = 0; i < 256; i++) {
163
	    for(i = 0; i < 256; i++) {
Lines 171-177 Link Here
171
			somedev++;
166
			somedev++;
172
			fd = open (dev, O_RDONLY);
167
			fd = open (dev, O_RDONLY);
173
			if (fd >= 0) {
168
			if (fd >= 0) {
174
				if(ioctl (fd, LOOP_GET_STATUS, &loopinfo) == 0)
169
				if (is_unused_loop_device(fd) == 0)
175
					someloop++;		/* in use */
170
					someloop++;		/* in use */
176
				else if (errno == ENXIO) {
171
				else if (errno == ENXIO) {
177
					close (fd);
172
					close (fd);
Lines 187-257 Link Here
187
182
188
	if (!somedev)
183
	if (!somedev)
189
		error(_("mount: could not find any device /dev/loop#"));
184
		error(_("mount: could not find any device /dev/loop#"));
190
	else if (!someloop) {
185
	else if (!someloop)
191
		error(_(
186
                error(_("mount: Could not find any loop device. Maybe this kernel does not know\n"
192
		    "mount: Could not find any loop device. Maybe this kernel "
187
			"       about the loop device? (If so, recompile or `modprobe loop'.)"));
193
		    "does not know\n"
188
	else
194
		    "       about the loop device? (If so, recompile or "
195
		    "`modprobe loop'.)"));
196
	} else
197
		error(_("mount: could not find any free loop device"));
189
		error(_("mount: could not find any free loop device"));
198
	return 0;
190
	return 0;
199
}
191
}
200
192
201
/*
193
static int rd_wr_retry(int fd, char *buf, int cnt, int w)
202
 * A function to read the passphrase either from the terminal or from
194
{
203
 * an open file descriptor.
195
	int x, y, z;
204
 */
196
205
static char *
197
	x = 0;
206
xgetpass(int pfd, const char *prompt) {
198
	while(x < cnt) {
207
	char *pass;
199
		y = cnt - x;
208
	int buflen, i;
200
		if(w) {
209
201
			z = write(fd, buf + x, y);
210
        if (pfd < 0) /* terminal */
202
		} else {
211
		return getpass(prompt);
203
			z = read(fd, buf + x, y);
212
204
			if (!z) return x;
213
	pass = NULL;
205
		}
214
	buflen = 0;
206
		if(z < 0) {
215
	for (i=0; ; i++) {
207
			if ((errno == EAGAIN) || (errno == ENOMEM) || (errno == ERESTART) || (errno == EINTR)) {
216
		if (i >= buflen-1) {
208
				continue;
217
				/* we're running out of space in the buffer.
209
			}
218
				 * Make it bigger: */
210
			return x;
219
			char *tmppass = pass;
211
		}
220
			buflen += 128;
212
		x += z;
221
			pass = realloc(tmppass, buflen);
213
	}
222
			if (pass == NULL) {
214
	return x;
223
				/* realloc failed. Stop reading. */
215
}
224
				error("Out of memory while reading passphrase");
216
225
				pass = tmppass; /* the old buffer hasn't changed */
217
static char *get_FD_pass(int fd)
226
				break;
218
{
219
	char *p = NULL;
220
	int x = 0, y = 0;
221
222
	do {
223
		if(y >= (x - 1)) {
224
			x += 128;
225
			if(!(p = realloc(p, x))) break;
226
		}
227
		if(rd_wr_retry(fd, p + y, 1, 0) != 1) break;
228
		if((p[y] == '\n') || !p[y]) break;
229
		y++;
230
	} while(1);
231
	if(p) p[y] = 0;
232
	return p;
233
}
234
235
static unsigned long long mystrtoull(char *s, int acceptAT)
236
{
237
	unsigned long long v = 0;
238
	int negative = 0;
239
240
	while ((*s == ' ') || (*s == '\t'))
241
		s++;
242
	if (acceptAT && (*s == '@')) {
243
		s++;
244
		negative = 1;
245
	}
246
	if (*s == '0') {
247
		s++;
248
		if ((*s == 'x') || (*s == 'X')) {
249
			s++;
250
			sscanf(s, "%llx", &v);
251
		} else {
252
			sscanf(s, "%llo", &v);
253
		}
254
	} else {
255
		sscanf(s, "%llu", &v);
256
	}
257
	return negative ? -v : v;
258
}
259
260
static char *do_GPG_pipe(char *pass)
261
{
262
	int     x, pfdi[2], pfdo[2];
263
	char    str[10], *a[16], *e[2], *h;
264
	pid_t   gpid;
265
	struct passwd *p;
266
267
	if((getuid() == 0) && gpgHomeDir && gpgHomeDir[0]) {
268
		h = gpgHomeDir;
269
	} else {
270
		if(!(p = getpwuid(getuid()))) {
271
			fprintf(stderr, _("Error: Unable to detect home directory for uid %d\n"), (int)getuid());
272
			return NULL;
273
		}
274
		h = p->pw_dir;
275
	}
276
	if(!(e[0] = malloc(strlen(h) + 6))) {
277
		nomem1:
278
		fprintf(stderr, _("Error: Unable to allocate memory\n"));
279
		return NULL;
280
	} 
281
	sprintf(e[0], "HOME=%s", h);
282
	e[1] = 0;
283
284
	if(pipe(&pfdi[0])) {
285
		nomem2:
286
		free(e[0]);
287
		goto nomem1;
288
	}
289
	if(pipe(&pfdo[0])) {
290
		close(pfdi[0]);
291
		close(pfdi[1]);
292
		goto nomem2;
293
	}
294
295
	/*
296
	 * When this code is run as part of losetup, normal read permissions
297
	 * affect the open() below because losetup is not setuid-root.
298
	 *
299
	 * When this code is run as part of mount, only root can set
300
	 * 'gpgKeyFile' and as such, only root can decide what file is opened
301
	 * below. However, since mount is usually setuid-root all non-root
302
	 * users can also open() the file too, but that file's contents are
303
	 * only piped to gpg. This readable-for-all is intended behaviour,
304
	 * and is very useful in situations where non-root users mount loop
305
	 * devices with their own gpg private key, and yet don't have access
306
	 * to the actual key used to encrypt loop device.
307
	 */
308
	if((x = open(gpgKeyFile, O_RDONLY)) == -1) {
309
		fprintf(stderr, _("Error: unable to open %s for reading\n"), gpgKeyFile);
310
		nomem3:
311
		free(e[0]);
312
		close(pfdo[0]);
313
		close(pfdo[1]);
314
		close(pfdi[0]);
315
		close(pfdi[1]);
316
		return NULL;
317
	}
318
319
	/*
320
	 * If someone puts a gpg key file at beginning of device and
321
	 * puts the real file system at some offset into the device,
322
	 * this code extracts that gpg key file into a temp file so gpg
323
	 * won't end up reading whole device when decrypting the key file.
324
	 *
325
	 * Example of encrypted cdrom mount with 8192 bytes reserved for gpg key file:
326
	 * mount -t iso9660 /dev/cdrom /cdrom -o loop=/dev/loop0,encryption=AES128,gpgkey=/dev/cdrom,offset=8192
327
	 *                  ^^^^^^^^^^                                                    ^^^^^^^^^^        ^^^^
328
	 */
329
	if(loopOffsetBytes && !strcmp(loopFileName, gpgKeyFile)) {
330
		FILE *f;
331
		char b[1024];
332
		long long cnt;
333
		int cnt2, cnt3;
334
335
		cnt = mystrtoull(loopOffsetBytes, 1);
336
		if(cnt < 0) cnt = -cnt;
337
		if(cnt > (1024 * 1024)) cnt = 1024 * 1024; /* sanity check */
338
		f = tmpfile();
339
		if(!f) {
340
			fprintf(stderr, _("Error: unable to create temp file\n"));
341
			close(x);
342
			goto nomem3;
343
		}
344
		while(cnt > 0) {
345
			cnt2 = sizeof(b);
346
			if(cnt < cnt2) cnt2 = cnt;
347
			cnt3 = rd_wr_retry(x, b, cnt2, 0);
348
			if(cnt3 && (fwrite(b, cnt3, 1, f) != 1)) {
349
				tmpWrErr:
350
				fprintf(stderr, _("Error: unable to write to temp file\n"));
351
				fclose(f);
352
				close(x);
353
				goto nomem3;
227
			}
354
			}
355
			if(cnt2 != cnt3) break;
356
			cnt -= cnt3;
357
		}
358
		if(fflush(f)) goto tmpWrErr;
359
		close(x);
360
		x = dup(fileno(f));
361
		fclose(f);
362
		lseek(x, 0L, SEEK_SET);
363
	}
364
365
	sprintf(str, "%d", pfdi[0]);
366
	if(!(gpid = fork())) {
367
		dup2(x, 0);
368
		dup2(pfdo[1], 1);
369
		close(x);
370
		close(pfdi[1]);
371
		close(pfdo[0]);
372
		close(pfdo[1]);
373
		if((x = open("/dev/null", O_WRONLY)) >= 0) {
374
			dup2(x, 2);
375
			close(x);
228
		}
376
		}
229
		if (read(pfd, pass+i, 1) != 1 || pass[i] == '\n')
377
		x = 0;
378
		a[x++] = "gpg";
379
		if(gpgHomeDir && gpgHomeDir[0]) {
380
			a[x++] = "--homedir";
381
			a[x++] = gpgHomeDir;
382
		}
383
		a[x++] = "--options";
384
		a[x++] = "/dev/null";
385
		a[x++] = "--quiet";
386
		a[x++] = "--batch";
387
		a[x++] = "--no-tty";
388
		a[x++] = "--passphrase-fd";
389
		a[x++] = str;
390
		a[x++] = "--decrypt";
391
		a[x] = 0;
392
		if(getuid() != geteuid())
393
			setuid(getuid());
394
		execve("/bin/gpg", &a[0], &e[0]);
395
		execve("/usr/bin/gpg", &a[0], &e[0]);
396
		execve("/usr/local/bin/gpg", &a[0], &e[0]);
397
		exit(1);
398
	}
399
	free(e[0]);
400
	close(x);
401
	close(pfdi[0]);
402
	close(pfdo[1]);
403
	if(gpid == -1) {
404
		close(pfdi[1]);
405
		close(pfdo[0]);
406
		goto nomem1;
407
	}
408
409
	x = strlen(pass);
410
	rd_wr_retry(pfdi[1], pass, x, 1);
411
	rd_wr_retry(pfdi[1], "\n", 1, 1);
412
	close(pfdi[1]);
413
	memset(pass, 0, x);
414
	x = 0;
415
	while(x < 64) {
416
		multiKeyPass[x] = get_FD_pass(pfdo[0]);
417
		if(!multiKeyPass[x]) {
418
			/* realloc() failed - abort */
419
			multiKeyPass[0] = 0;
230
			break;
420
			break;
421
		}
422
		if(strlen(multiKeyPass[x]) < LOOP_PASSWORD_MIN_LENGTH) break;
423
		x++;
424
	}
425
	if(x == 64)
426
		multiKeyMode = 1;
427
	close(pfdo[0]);
428
	waitpid(gpid, &x, 0);
429
	if(!multiKeyPass[0]) goto nomem1;
430
	return multiKeyPass[0];
431
}
432
433
static char *sGetPass(int minLen, int warnLen)
434
{
435
	char *p, *s, *seed;
436
	int i, ask2;
437
438
	if(!passFDnumber) {
439
		p = getpass(_("Password: "));
440
		ask2 = passAskTwice ? 1 : 0;
441
	} else {
442
		p = get_FD_pass(atoi(passFDnumber));
443
		ask2 = 0;
231
	}
444
	}
232
	if (pass == NULL)
445
	if(!p) goto nomem;
233
		return "";
446
	if(gpgKeyFile && gpgKeyFile[0]) {
234
	else {
447
		if(ask2) {
235
		pass[i] = 0;
448
			i = strlen(p);
236
		return pass;
449
			s = malloc(i + 1);
450
			if(!s) goto nomem;
451
			strcpy(s, p);
452
			p = getpass(_("Retype password: "));
453
			if(!p) goto nomem;
454
			if(strcmp(s, p)) goto compareErr;
455
			memset(s, 0, i);
456
			free(s);
457
			ask2 = 0;
458
		}
459
		p = do_GPG_pipe(p);
460
		if(!p) return(NULL);
461
		if(!p[0]) {
462
			fprintf(stderr, _("Error: gpg key file decryption failed\n"));
463
			return(NULL);
464
		}
465
		if(multiKeyMode) return(p);
237
	}
466
	}
467
	i = strlen(p);
468
	if(i < minLen) {
469
		fprintf(stderr, _("Error: Password must be at least %d characters.\n"), minLen);
470
		return(NULL);
471
	}
472
	seed = passSeedString;
473
	if(!seed) seed = "";
474
	s = malloc(i + strlen(seed) + 1);
475
	if(!s) {
476
		nomem:
477
		fprintf(stderr, _("Error: Unable to allocate memory\n"));
478
		return(NULL);
479
	}
480
	strcpy(s, p);
481
	memset(p, 0, i);
482
	if(ask2) {
483
		p = getpass(_("Retype password: "));
484
		if(!p) goto nomem;
485
		if(strcmp(s, p)) {
486
			compareErr:
487
			fprintf(stderr, _("Error: Passwords are not identical\n"));
488
			return(NULL);
489
		}
490
		memset(p, 0, i);
491
	}
492
	if(i < warnLen) {
493
		fprintf(stderr, 
494
		      _("\n"
495
			"WARNING - WARNING - WARNING - WARNING - WARNING - WARNING - WARNING\n"
496
			"\n"
497
			"Passwords shorter than %d characters are considered too short and insecure.\n"
498
			"Use of rmd160 password hash permits use of such short passwords for\n"
499
			"compatibility with other systems that do not enforce minimum length.\n"
500
			"Hopefully this message is annoying enough that you discontinue using such\n"
501
			"short passwords.\n"
502
			"\n"
503
			"WARNING - WARNING - WARNING - WARNING - WARNING - WARNING - WARNING\n"
504
			"\n")
505
			, LOOP_PASSWORD_MIN_LENGTH);
506
	}
507
	strcat(s, seed);
508
	return(s);
238
}
509
}
239
510
240
static int
511
/* this is for compatibility with historic loop-AES version */
241
digits_only(const char *s) {
512
static void unhashed1_key_setup(unsigned char *keyStr, int ile, unsigned char *keyBuf, int bufSize)
242
	while (*s)
513
{
243
		if (!isdigit(*s++))
514
	register int    x, y, z, cnt = ile;
244
			return 0;
515
	unsigned char   *kp;
245
	return 1;
516
517
	memset(keyBuf, 0, bufSize);
518
	kp = keyStr;
519
	for(x = 0; x < (bufSize * 8); x += 6) {
520
		y = *kp++;
521
		if(--cnt <= 0) {
522
			kp = keyStr;
523
			cnt = ile;
524
		}
525
		if((y >= '0') && (y <= '9')) y -= '0';
526
		else if((y >= 'A') && (y <= 'Z')) y -= ('A' - 10);
527
		else if((y >= 'a') && (y <= 'z')) y -= ('a' - 36);
528
		else if((y == '.') || (y == '/')) y += (62 - '.');
529
		else y &= 63;
530
		z = x >> 3;
531
		if(z < bufSize) {
532
			keyBuf[z] |= y << (x & 7);
533
		}
534
		z++;
535
		if(z < bufSize) {
536
			keyBuf[z] |= y >> (8 - (x & 7));
537
		}
538
	}
539
}
540
541
/* this is for compatibility with mainline mount */
542
static void unhashed2_key_setup(unsigned char *keyStr, int ile, unsigned char *keyBuf, int bufSize)
543
{
544
	memset(keyBuf, 0, bufSize);
545
	strncpy(keyBuf, keyStr, bufSize - 1);
546
	keyBuf[bufSize - 1] = 0;
547
}
548
549
static void rmd160HashTwiceWithA(unsigned char *ib, int ile, unsigned char *ob, int ole)
550
{
551
	char tmpBuf[20 + 20];
552
	char pwdCopy[130];
553
554
	if(ole < 1) return;
555
	memset(ob, 0, ole);
556
	if(ole > 40) ole = 40;
557
	rmd160_hash_buffer(&tmpBuf[0], ib, ile);
558
	pwdCopy[0] = 'A';
559
	if(ile > sizeof(pwdCopy) - 1) ile = sizeof(pwdCopy) - 1;
560
	memcpy(pwdCopy + 1, ib, ile);
561
	rmd160_hash_buffer(&tmpBuf[20], pwdCopy, ile + 1);
562
	memcpy(ob, tmpBuf, ole);
563
	memset(tmpBuf, 0, sizeof(tmpBuf));
564
	memset(pwdCopy, 0, sizeof(pwdCopy));
246
}
565
}
247
566
248
int
567
int
249
set_loop(const char *device, const char *file, int offset,
568
set_loop(const char *device, const char *file, int *loopro) {
250
	 const char *encryption, int pfd, int *loopro) {
569
	struct loop_info64 loopinfo;
251
	struct loop_info64 loopinfo64;
570
	int fd, ffd, mode, i;
252
	int fd, ffd, mode;
571
	char *pass, *apiName = NULL;
253
	char *pass;
572
	void (*hashFunc)(unsigned char *, int, unsigned char *, int);
573
	unsigned char multiKeyBits[64][32];
254
574
575
	loopFileName = (char *)file;
576
	multiKeyMode = 0;
255
	mode = (*loopro ? O_RDONLY : O_RDWR);
577
	mode = (*loopro ? O_RDONLY : O_RDWR);
256
	if ((ffd = open(file, mode)) < 0) {
578
	if ((ffd = open(file, mode)) < 0) {
257
		if (!*loopro && errno == EROFS)
579
		if (!*loopro && errno == EROFS)
Lines 267-287 Link Here
267
	}
589
	}
268
	*loopro = (mode == O_RDONLY);
590
	*loopro = (mode == O_RDONLY);
269
591
270
	memset(&loopinfo64, 0, sizeof(loopinfo64));
592
	memset (&loopinfo, 0, sizeof (loopinfo));
271
593
	xstrncpy (loopinfo.lo_file_name, file, LO_NAME_SIZE);
272
	xstrncpy(loopinfo64.lo_file_name, file, LO_NAME_SIZE);
594
	if (loopEncryptionType)
273
595
		loopinfo.lo_encrypt_type = loop_crypt_type (loopEncryptionType, &loopinfo.lo_encrypt_key_size, &apiName);
274
	if (encryption && *encryption) {
596
	if (loopOffsetBytes)
275
		if (digits_only(encryption)) {
597
		loopinfo.lo_offset = mystrtoull(loopOffsetBytes, 1);
276
			loopinfo64.lo_encrypt_type = atoi(encryption);
598
	if (loopSizeBytes)
277
		} else {
599
		loopinfo.lo_sizelimit = mystrtoull(loopSizeBytes, 0);
278
			loopinfo64.lo_encrypt_type = LO_CRYPT_CRYPTOAPI;
279
			snprintf(loopinfo64.lo_crypt_name, LO_NAME_SIZE,
280
				 "%s", encryption);
281
		}
282
	}
283
284
	loopinfo64.lo_offset = offset;
285
600
286
#ifdef MCL_FUTURE  
601
#ifdef MCL_FUTURE  
287
	/*
602
	/*
Lines 296-405 Link Here
296
	}
611
	}
297
#endif
612
#endif
298
613
299
	switch (loopinfo64.lo_encrypt_type) {
614
	switch (loopinfo.lo_encrypt_type) {
300
	case LO_CRYPT_NONE:
615
	case LO_CRYPT_NONE:
301
		loopinfo64.lo_encrypt_key_size = 0;
616
		loopinfo.lo_encrypt_key_size = 0;
302
		break;
617
		break;
303
	case LO_CRYPT_XOR:
618
	case LO_CRYPT_XOR:
304
		pass = getpass(_("Password: "));
619
		pass = sGetPass (1, 0);
305
		xstrncpy(loopinfo64.lo_encrypt_key, pass, LO_KEY_SIZE);
620
		if(!pass) return(1);
306
		loopinfo64.lo_encrypt_key_size =
621
		xstrncpy (loopinfo.lo_encrypt_key, pass, LO_KEY_SIZE);
307
			strlen(loopinfo64.lo_encrypt_key);
622
		loopinfo.lo_encrypt_key_size = strlen(loopinfo.lo_encrypt_key);
623
		break;
624
	case 3:   /* LO_CRYPT_FISH2 */
625
	case 4:   /* LO_CRYPT_BLOW */
626
	case 7:   /* LO_CRYPT_SERPENT */
627
	case 8:   /* LO_CRYPT_MARS */
628
	case 11:  /* LO_CRYPT_RC6 */
629
	case 12:  /* LO_CRYPT_DES_EDE3 */
630
	case 16:  /* LO_CRYPT_AES */
631
	case 18:  /* LO_CRYPT_CRYPTOAPI */
632
		/* set default hash function */
633
		hashFunc = sha256_hash_buffer;
634
		if(loopinfo.lo_encrypt_key_size == 24) hashFunc = sha384_hash_buffer;
635
		if(loopinfo.lo_encrypt_key_size == 32) hashFunc = sha512_hash_buffer;
636
		/* possibly override default hash function */
637
		if(passHashFuncName) {
638
			if(!strcasecmp(passHashFuncName, "sha256")) {
639
				hashFunc = sha256_hash_buffer;
640
			} else if(!strcasecmp(passHashFuncName, "sha384")) {
641
				hashFunc = sha384_hash_buffer;
642
			} else if(!strcasecmp(passHashFuncName, "sha512")) {
643
				hashFunc = sha512_hash_buffer;
644
			} else if(!strcasecmp(passHashFuncName, "rmd160")) {
645
				hashFunc = rmd160HashTwiceWithA;
646
			} else if(!strcasecmp(passHashFuncName, "unhashed1")) {
647
				hashFunc = unhashed1_key_setup;
648
			} else if(!strcasecmp(passHashFuncName, "unhashed2")) {
649
				hashFunc = unhashed2_key_setup;
650
			}
651
		}
652
		pass = sGetPass ((hashFunc == rmd160HashTwiceWithA) ? 1 : LOOP_PASSWORD_MIN_LENGTH, LOOP_PASSWORD_MIN_LENGTH);
653
		if(!pass) return(1);
654
		i = strlen(pass);
655
		if(hashFunc == unhashed1_key_setup) {
656
			/* this is for compatibility with historic loop-AES version */
657
			loopinfo.lo_encrypt_key_size = 16;             /* 128 bits */
658
			if(i >= 32) loopinfo.lo_encrypt_key_size = 24; /* 192 bits */
659
			if(i >= 43) loopinfo.lo_encrypt_key_size = 32; /* 256 bits */
660
		}
661
		(*hashFunc)(pass, i, &loopinfo.lo_encrypt_key[0], sizeof(loopinfo.lo_encrypt_key));
662
		if(multiKeyMode) {
663
			int r = 0, t;
664
			while(r < 64) {
665
				t = strlen(multiKeyPass[r]);
666
				(*hashFunc)(multiKeyPass[r], t, &multiKeyBits[r][0], 32);
667
				memset(multiKeyPass[r], 0, t);
668
				/*
669
				 * MultiKeyMode uses md5 IV. One key mode uses sector IV. Sector IV
670
				 * and md5 IV are computed differently. This first key byte XOR with
671
				 * 0x55 is needed to cause complete decrypt failure in cases where
672
				 * data is encrypted with sector IV and decrypted with md5 IV or
673
				 * vice versa. If identical key was used but only IV was computed
674
				 * differently, only first plaintext block of 512 byte CBC chain
675
				 * would decrypt incorrectly and rest would decrypt correctly.
676
				 * Partially correct decryption is dangerous. Decrypting all blocks
677
				 * incorrectly is safer because file system mount will simply fail.
678
				 */
679
				multiKeyBits[r][0] ^= 0x55;
680
				r++;
681
			}
682
		} else if(passIterThousands) {
683
			aes_context ctx;
684
			unsigned long iter = 0;
685
			unsigned char tempkey[32];
686
			/*
687
			 * Set up AES-256 encryption key using same password and hash function
688
			 * as before but with password bit 0 flipped before hashing. That key
689
			 * is then used to encrypt actual loop key 'itercountk' thousand times.
690
			 */
691
			pass[0] ^= 1;
692
			(*hashFunc)(pass, i, &tempkey[0], 32);
693
			aes_set_key(&ctx, &tempkey[0], 32, 0);
694
			sscanf(passIterThousands, "%lu", &iter);
695
			iter *= 1000;
696
			while(iter > 0) {
697
				/* encrypt both 128bit blocks with AES-256 */
698
				aes_encrypt(&ctx, &loopinfo.lo_encrypt_key[ 0], &loopinfo.lo_encrypt_key[ 0]);
699
				aes_encrypt(&ctx, &loopinfo.lo_encrypt_key[16], &loopinfo.lo_encrypt_key[16]);
700
				/* exchange upper half of first block with lower half of second block */
701
				memcpy(&tempkey[0], &loopinfo.lo_encrypt_key[8], 8);
702
				memcpy(&loopinfo.lo_encrypt_key[8], &loopinfo.lo_encrypt_key[16], 8);
703
				memcpy(&loopinfo.lo_encrypt_key[16], &tempkey[0], 8);
704
				iter--;
705
			}
706
			memset(&ctx, 0, sizeof(ctx));
707
			memset(&tempkey[0], 0, sizeof(tempkey));
708
		}
709
		memset(pass, 0, i);   /* erase original password */
308
		break;
710
		break;
309
	default:
711
	default:
310
		pass = xgetpass(pfd, _("Password: "));
712
		fprintf (stderr, _("Error: don't know how to get key for encryption system %d\n"), loopinfo.lo_encrypt_type);
311
		xstrncpy(loopinfo64.lo_encrypt_key, pass, LO_KEY_SIZE);
713
		return 1;
312
		loopinfo64.lo_encrypt_key_size = LO_KEY_SIZE;
714
	}
715
716
	if(loInitValue) {
717
		/* cipher modules are free to do whatever they want with this value */
718
		i = 0;
719
		sscanf(loInitValue, "%d", &i);
720
		loopinfo.lo_init[0] = i;
313
	}
721
	}
314
722
315
	if (ioctl(fd, LOOP_SET_FD, ffd) < 0) {
723
	if (ioctl(fd, LOOP_SET_FD, ffd) < 0) {
316
		perror("ioctl: LOOP_SET_FD");
724
		perror("ioctl: LOOP_SET_FD");
725
		memset(loopinfo.lo_encrypt_key, 0, sizeof(loopinfo.lo_encrypt_key));
726
		memset(&multiKeyBits[0][0], 0, sizeof(multiKeyBits));
317
		return 1;
727
		return 1;
318
	}
728
	}
319
	close (ffd);
729
	close (ffd);
320
730
321
	if (ioctl(fd, LOOP_SET_STATUS64, &loopinfo64) < 0) {
731
	/* type 18 == LO_CRYPT_CRYPTOAPI */
322
		struct loop_info loopinfo;
732
	if ((loopinfo.lo_encrypt_type == 18) || (loop_set_status64_ioctl(fd, &loopinfo) < 0)) {
323
		int errsv = errno;
733
		/* direct cipher interface failed - try CryptoAPI interface now */
324
734
		if(!apiName || (try_cryptoapi_loop_interface(fd, &loopinfo, apiName) < 0)) {
325
		errno = loop_info64_to_old(&loopinfo64, &loopinfo);
735
			fprintf(stderr, _("ioctl: LOOP_SET_STATUS: %s, requested cipher or key length (%d bits) not supported by kernel\n"), strerror(errno), loopinfo.lo_encrypt_key_size << 3);
326
		if (errno) {
736
			(void) ioctl (fd, LOOP_CLR_FD, 0);
327
			errno = errsv;
737
			memset(loopinfo.lo_encrypt_key, 0, sizeof(loopinfo.lo_encrypt_key));
328
			perror("ioctl: LOOP_SET_STATUS64");
738
			memset(&multiKeyBits[0][0], 0, sizeof(multiKeyBits));
329
			goto fail;
739
			return 1;
330
		}
331
332
		if (ioctl(fd, LOOP_SET_STATUS, &loopinfo) < 0) {
333
			perror("ioctl: LOOP_SET_STATUS");
334
			goto fail;
335
		}
740
		}
336
	}
741
	}
742
	memset(loopinfo.lo_encrypt_key, 0, sizeof(loopinfo.lo_encrypt_key));
337
743
338
	close (fd);
744
	if(multiKeyMode && (ioctl(fd, LOOP_MULTI_KEY_SETUP, &multiKeyBits[0][0]) < 0)) {
339
	if (verbose > 1)
745
		perror("ioctl: LOOP_MULTI_KEY_SETUP");
340
		printf(_("set_loop(%s,%s,%d): success\n"),
746
		(void) ioctl (fd, LOOP_CLR_FD, 0);
341
		       device, file, offset);
747
		memset(&multiKeyBits[0][0], 0, sizeof(multiKeyBits));
342
	return 0;
343
344
 fail:
345
	(void) ioctl (fd, LOOP_CLR_FD, 0);
346
	close (fd);
347
	return 1;
348
}
349
350
int 
351
del_loop (const char *device) {
352
	int fd;
353
354
	if ((fd = open (device, O_RDONLY)) < 0) {
355
		int errsv = errno;
356
		fprintf(stderr, _("loop: can't delete device %s: %s\n"),
357
			device, strerror (errsv));
358
		return 1;
359
	}
360
	if (ioctl (fd, LOOP_CLR_FD, 0) < 0) {
361
		perror ("ioctl: LOOP_CLR_FD");
362
		return 1;
748
		return 1;
363
	}
749
	}
750
	memset(&multiKeyBits[0][0], 0, sizeof(multiKeyBits));
751
364
	close (fd);
752
	close (fd);
365
	if (verbose > 1)
753
	if (verbose > 1)
366
		printf(_("del_loop(%s): success\n"), device);
754
		printf(_("set_loop(%s,%s): success\n"), device, file);
367
	return 0;
755
	return 0;
368
}
756
}
369
757
370
#else /* no LOOP_SET_FD defined */
371
static void
372
mutter(void) {
373
	fprintf(stderr,
374
		_("This mount was compiled without loop support. "
375
		  "Please recompile.\n"));
376
}  
377
378
int
379
set_loop (const char *device, const char *file, int offset,
380
	  const char *encryption, int *loopro) {
381
	mutter();
382
	return 1;
383
}
384
385
int
386
del_loop (const char *device) {
387
	mutter();
388
	return 1;
389
}
390
391
char *
392
find_unused_loop_device (void) {
393
	mutter();
394
	return 0;
395
}
396
397
#endif
398
399
#ifdef MAIN
758
#ifdef MAIN
400
759
401
#ifdef LOOP_SET_FD
402
403
#include <getopt.h>
760
#include <getopt.h>
404
#include <stdarg.h>
761
#include <stdarg.h>
405
762
Lines 409-418 Link Here
409
static void
766
static void
410
usage(void) {
767
usage(void) {
411
	fprintf(stderr, _("usage:\n\
768
	fprintf(stderr, _("usage:\n\
412
  %s loop_device                                      # give info\n\
769
  %s [-e encryption] [options] loop_device file  # setup\n\
413
  %s -d loop_device                                   # delete\n\
770
  %s -F [options] loop_device [file]   # setup, read /etc/fstab\n\
414
  %s [ -e encryption ] [ -o offset ] loop_device file # setup\n"),
771
  %s loop_device                       # give info\n\
415
		progname, progname, progname);
772
  %s -a                                # give info of all loops\n\
773
  %s -d loop_device                    # delete\n\
774
options:  -o offset  -s sizelimit  -p passwdfd  -S pseed  -H phash\n\
775
          -I loinit  -T  -K gpgkey  -G gpghome  -C itercountk  -v  -r\n"),
776
		progname, progname, progname, progname, progname);
416
	exit(1);
777
	exit(1);
417
}
778
}
418
779
Lines 443-513 Link Here
443
	fprintf (stderr, "\n");
804
	fprintf (stderr, "\n");
444
}
805
}
445
806
807
void
808
show_all_loops(void)
809
{
810
	char dev[20];
811
	char *lfmt[] = { "/dev/loop%d", "/dev/loop/%d" };
812
	int i, j, fd, x;
813
	struct stat statbuf;
814
815
	for(i = 0; i < 256; i++) {
816
		for(j = (sizeof(lfmt) / sizeof(lfmt[0])) - 1; j >= 0; j--) {
817
			sprintf(dev, lfmt[j], i);
818
			if(stat(dev, &statbuf) == 0 && S_ISBLK(statbuf.st_mode)) {
819
				fd = open(dev, O_RDONLY);
820
				if(fd >= 0) {
821
					x = is_unused_loop_device(fd);
822
					close(fd);
823
					if(x == 0) {
824
						show_loop(dev);
825
						j = 0;
826
					}
827
				}
828
			}
829
		}
830
	}
831
}
832
833
int
834
read_options_from_fstab(char *loopToFind, char **partitionPtr)
835
{
836
	FILE *f;
837
	struct mntent *m;
838
	int y, foundMatch = 0;
839
	char *opt;
840
	struct options {
841
		char *name;	/* name of /etc/fstab option */
842
		char **dest;	/* destination where it is written to */
843
		char *line;	/* temp */
844
	};
845
	struct options tbl[] = {
846
		{ "device/file name ",	partitionPtr },	/* must be index 0 */
847
		{ "loop=",		&loopToFind },	/* must be index 1 */
848
		{ "offset=",		&loopOffsetBytes },
849
		{ "sizelimit=",		&loopSizeBytes },
850
		{ "encryption=",	&loopEncryptionType },
851
		{ "pseed=",		&passSeedString },
852
		{ "phash=",		&passHashFuncName },
853
		{ "loinit=",		&loInitValue },
854
		{ "gpgkey=",		&gpgKeyFile },
855
		{ "gpghome=",		&gpgHomeDir },
856
		{ "itercountk=",	&passIterThousands },
857
	};
858
	struct options *p;
859
860
	if (!(f = setmntent("/etc/fstab", "r"))) {
861
		fprintf(stderr, _("Error: unable to open /etc/fstab for reading\n"));
862
		return 0;
863
	}
864
	while ((m = getmntent(f)) != NULL) {
865
		tbl[0].line = xstrdup(m->mnt_fsname);
866
		p = &tbl[1];
867
		do {
868
			p->line = NULL;
869
		} while (++p < &tbl[sizeof(tbl) / sizeof(struct options)]);
870
		for (opt = strtok(xstrdup(m->mnt_opts), ","); opt != NULL; opt = strtok(NULL, ",")) {
871
			p = &tbl[1];
872
			do {
873
				y = strlen(p->name);
874
				if (!strncmp(opt, p->name, y))
875
					p->line = opt + y;
876
			} while (++p < &tbl[sizeof(tbl) / sizeof(struct options)]);
877
		}
878
		if (tbl[1].line && !strcmp(loopToFind, tbl[1].line)) {
879
			if (++foundMatch > 1) {
880
				fprintf(stderr, _("Error: multiple loop=%s options found in /etc/fstab\n"), loopToFind);
881
				endmntent(f);
882
				return 0;
883
			}
884
			p = &tbl[0];
885
			do {
886
				if (!*p->dest && p->line) {
887
					*p->dest = p->line;
888
					if (verbose)
889
						printf(_("using %s%s from /etc/fstab\n"), p->name, p->line);
890
				}
891
			} while (++p < &tbl[sizeof(tbl) / sizeof(struct options)]);
892
		}
893
	}
894
	endmntent(f);
895
	if (foundMatch == 0) {
896
		fprintf(stderr, _("Error: loop=%s option not found in /etc/fstab\n"), loopToFind);
897
	}
898
	return foundMatch;
899
}
900
446
int
901
int
447
main(int argc, char **argv) {
902
main(int argc, char **argv) {
448
	char *offset, *encryption, *passfd;
903
	char *partitionName = NULL;
449
	int delete, off, c;
904
	int delete,c,option_a=0,option_F=0;
450
	int res = 0;
905
	int res = 0;
451
	int ro = 0;
906
	int ro = 0;
452
	int pfd = -1;
453
907
454
	setlocale(LC_ALL, "");
908
	setlocale(LC_ALL, "");
455
	bindtextdomain(PACKAGE, LOCALEDIR);
909
	bindtextdomain(PACKAGE, LOCALEDIR);
456
	textdomain(PACKAGE);
910
	textdomain(PACKAGE);
457
911
458
	delete = off = 0;
912
	delete = 0;
459
	offset = encryption = passfd = NULL;
460
	progname = argv[0];
913
	progname = argv[0];
461
	while ((c = getopt(argc,argv,"de:E:o:p:v")) != -1) {
914
	while ((c = getopt(argc,argv,"aC:de:FG:H:I:K:o:p:rs:S:Tv")) != -1) {
462
		switch (c) {
915
		switch (c) {
916
		case 'a':		/* show status of all loops */
917
			option_a = 1;
918
			break;
919
		case 'C':
920
			passIterThousands = optarg;
921
			break;
463
		case 'd':
922
		case 'd':
464
			delete = 1;
923
			delete = 1;
465
			break;
924
			break;
466
		case 'E':
467
		case 'e':
925
		case 'e':
468
			encryption = optarg;
926
			loopEncryptionType = optarg;
927
			break;
928
		case 'F':		/* read loop related options from /etc/fstab */
929
			option_F = 1;
930
			break;
931
		case 'G':               /* GnuPG home dir */
932
			gpgHomeDir = optarg;
933
			break;
934
		case 'H':               /* passphrase hash function name */
935
			passHashFuncName = optarg;
936
			break;
937
		case 'I':               /* lo_init[0] value (in string form)  */
938
			loInitValue = optarg;
939
			break;
940
		case 'K':               /* GnuPG key file name */
941
			gpgKeyFile = optarg;
469
			break;
942
			break;
470
		case 'o':
943
		case 'o':
471
			offset = optarg;
944
			loopOffsetBytes = optarg;
945
			break;
946
		case 'p':               /* read passphrase from given fd */
947
			passFDnumber = optarg;
948
			break;
949
		case 'r':               /* read-only */
950
			ro = 1;
472
			break;
951
			break;
473
		case 'p':
952
		case 's':
474
			passfd = optarg;
953
			loopSizeBytes = optarg;
954
			break;
955
		case 'S':               /* optional seed for passphrase */
956
			passSeedString = optarg;
957
			break;
958
		case 'T':               /* ask passphrase _twice_ */
959
			passAskTwice = "T";
475
			break;
960
			break;
476
		case 'v':
961
		case 'v':
477
			verbose = 1;
962
			verbose++;
478
			break;
963
			break;
479
		default:
964
		default:
480
			usage();
965
			usage();
481
		}
966
		}
482
	}
967
	}
483
	if (argc == 1) usage();
968
	if (argc == 1) usage();
484
	if ((delete && (argc != optind+1 || encryption || offset)) ||
969
	if (option_a) {
970
		if (delete || (argc != optind)) usage();
971
		show_all_loops();
972
		exit(0);
973
	}
974
	if ((delete && (argc != optind+1 || loopEncryptionType || loopOffsetBytes || loopSizeBytes || option_F)) ||
485
	    (!delete && (argc < optind+1 || argc > optind+2)))
975
	    (!delete && (argc < optind+1 || argc > optind+2)))
486
		usage();
976
		usage();
487
	if (argc == optind+1) {
977
	if (argc > optind+1)
488
		if (delete)
978
		partitionName = argv[optind+1];
489
			res = del_loop(argv[optind]);
979
	if (option_F && (read_options_from_fstab(argv[optind], &partitionName) != 1))
490
		else
980
		exit(1);
491
			res = show_loop(argv[optind]);
981
	if (delete) {
982
		res = del_loop(argv[optind]);
983
	} else if ((argc == optind+1) && !option_F) {
984
		res = show_loop(argv[optind]);
492
	} else {
985
	} else {
493
		if (offset && sscanf(offset,"%d",&off) != 1)
986
		res = set_loop(argv[optind],partitionName,&ro);
494
			usage();
495
		if (passfd && sscanf(passfd,"%d",&pfd) != 1)
496
			usage();
497
		res = set_loop(argv[optind], argv[optind+1], off,
498
			       encryption, pfd, &ro);
499
	}
987
	}
500
	return res;
988
	return res;
501
}
989
}
502
503
#else /* LOOP_SET_FD not defined */
504
505
int
506
main(int argc, char **argv) {
507
	fprintf(stderr,
508
		_("No loop support was available at compile time. "
509
		  "Please recompile.\n"));
510
	return -1;
511
}
512
#endif
513
#endif
990
#endif
(-)util-linux-2.12/mount/lomount.h (-2 / +13 lines)
Lines 1-6 Link Here
1
extern int verbose;
1
extern int verbose;
2
extern int set_loop(const char *, const char *, int, const char *,
2
extern int set_loop(const char *, const char *, int *);
3
		    int, int *);
4
extern int del_loop(const char *);
3
extern int del_loop(const char *);
5
extern int is_loop_device(const char *);
4
extern int is_loop_device(const char *);
6
extern char * find_unused_loop_device(void);
5
extern char * find_unused_loop_device(void);
6
7
extern char *passFDnumber;
8
extern char *passAskTwice;
9
extern char *passSeedString;
10
extern char *passHashFuncName;
11
extern char *passIterThousands;
12
extern char *loInitValue;
13
extern char *gpgKeyFile;
14
extern char *gpgHomeDir;
15
extern char *loopOffsetBytes;
16
extern char *loopSizeBytes;
17
extern char *loopEncryptionType;
(-)util-linux-2.12/mount/loop.c (+221 lines)
Line 0 Link Here
1
/*
2
 *  loop.c
3
 *
4
 *  Copyright 2003 by Jari Ruusu.
5
 *  Redistribution of this file is permitted under the GNU GPL
6
 */
7
8
/* collection of loop helper functions used by losetup, mount and swapon */
9
10
#include <stdio.h>
11
#include <string.h>
12
#include <ctype.h>
13
#include <sys/ioctl.h>
14
#include <sys/types.h>
15
#include <errno.h>
16
#include "loop.h"
17
18
static void convert_info_to_info64(struct loop_info *info, struct loop_info64 *info64)
19
{
20
	memset(info64, 0, sizeof(*info64));
21
	info64->lo_number = info->lo_number;
22
	info64->lo_device = info->lo_device;
23
	info64->lo_inode = info->lo_inode;
24
	info64->lo_rdevice = info->lo_rdevice;
25
	info64->lo_offset = info->lo_offset;
26
	info64->lo_encrypt_type = info->lo_encrypt_type;
27
	info64->lo_encrypt_key_size = info->lo_encrypt_key_size;
28
	info64->lo_flags = info->lo_flags;
29
	info64->lo_init[0] = info->lo_init[0];
30
	info64->lo_init[1] = info->lo_init[1];
31
	info64->lo_sizelimit = 0;
32
	if (info->lo_encrypt_type == 18) /* LO_CRYPT_CRYPTOAPI */
33
		memcpy(info64->lo_crypt_name, info->lo_name, sizeof(info64->lo_crypt_name));
34
	else
35
		memcpy(info64->lo_file_name, info->lo_name, sizeof(info64->lo_file_name));
36
	memcpy(info64->lo_encrypt_key, info->lo_encrypt_key, sizeof(info64->lo_encrypt_key));
37
}
38
39
static int convert_info64_to_info(struct loop_info64 *info64, struct loop_info *info)
40
{
41
	memset(info, 0, sizeof(*info));
42
	info->lo_number = info64->lo_number;
43
	info->lo_device = info64->lo_device;
44
	info->lo_inode = info64->lo_inode;
45
	info->lo_rdevice = info64->lo_rdevice;
46
	info->lo_offset = info64->lo_offset;
47
	info->lo_encrypt_type = info64->lo_encrypt_type;
48
	info->lo_encrypt_key_size = info64->lo_encrypt_key_size;
49
	info->lo_flags = info64->lo_flags;
50
	info->lo_init[0] = info64->lo_init[0];
51
	info->lo_init[1] = info64->lo_init[1];
52
	if (info->lo_encrypt_type == 18) /* LO_CRYPT_CRYPTOAPI */
53
		memcpy(info->lo_name, info64->lo_crypt_name, sizeof(info->lo_name));
54
	else
55
		memcpy(info->lo_name, info64->lo_file_name, sizeof(info->lo_name));
56
	memcpy(info->lo_encrypt_key, info64->lo_encrypt_key, sizeof(info->lo_encrypt_key));
57
58
	/* error in case values were truncated */
59
	if (info->lo_device != info64->lo_device ||
60
	    info->lo_rdevice != info64->lo_rdevice ||
61
	    info->lo_inode != info64->lo_inode ||
62
	    info->lo_offset != info64->lo_offset ||
63
	    info64->lo_sizelimit) {
64
		errno = EOVERFLOW;
65
		return -1;
66
	}
67
	return 0;
68
}
69
70
int loop_set_status64_ioctl(int fd, struct loop_info64 *info64)
71
{
72
	struct loop_info info;
73
	struct loop_info64 tmp;
74
	int r;
75
76
	/*
77
	 * This ugly work around is needed because some
78
	 * Red Hat kernels are using same ioctl code:
79
	 *  	#define LOOP_CHANGE_FD 0x4C04
80
	 * vs.
81
	 *	#define LOOP_SET_STATUS64 0x4C04
82
	 * that is used by modern loop driver.
83
	 *
84
	 * Attempt to detect presense of LOOP_GET_STATUS64
85
	 * ioctl before issuing LOOP_SET_STATUS64 ioctl.
86
	 * Red Hat kernels with above LOOP_CHANGE_FD damage
87
	 * should return -1 and set errno to EINVAL.
88
	 */
89
	r = ioctl(fd, LOOP_GET_STATUS64, &tmp);
90
	memset(&tmp, 0, sizeof(tmp));
91
	if ((r == 0) || (errno != EINVAL)) {
92
		r = ioctl(fd, LOOP_SET_STATUS64, info64);
93
		if (!r)
94
			return 0;
95
	}
96
	r = convert_info64_to_info(info64, &info);
97
	if (!r)
98
		r = ioctl(fd, LOOP_SET_STATUS, &info);
99
100
	/* don't leave copies of encryption key on stack */
101
	memset(&info, 0, sizeof(info));
102
	return r;
103
}
104
105
int loop_get_status64_ioctl(int fd, struct loop_info64 *info64)
106
{
107
	struct loop_info info;
108
	int r;
109
110
	memset(info64, 0, sizeof(*info64));
111
	r = ioctl(fd, LOOP_GET_STATUS64, info64);
112
	if (!r)
113
		return 0;
114
	r = ioctl(fd, LOOP_GET_STATUS, &info);
115
	if (!r)
116
		convert_info_to_info64(&info, info64);
117
118
	/* don't leave copies of encryption key on stack */
119
	memset(&info, 0, sizeof(info));
120
	return r;
121
}
122
123
/* returns: 1=unused 0=busy */
124
int is_unused_loop_device(int fd)
125
{
126
	struct loop_info64 info64;
127
	struct loop_info info;
128
	int r;
129
130
	r = ioctl(fd, LOOP_GET_STATUS64, &info64);
131
	memset(&info64, 0, sizeof(info64));
132
	if (!r)
133
		return 0;
134
	if (errno == ENXIO)
135
		return 1;
136
137
	r = ioctl(fd, LOOP_GET_STATUS, &info);
138
	memset(&info, 0, sizeof(info));
139
	if (!r)
140
		return 0;
141
	if (errno == ENXIO)
142
		return 1;
143
	if (errno == EOVERFLOW)
144
		return 0;
145
	return 1;
146
}
147
148
struct loop_crypt_type_struct loop_crypt_type_tbl[] = {
149
	{  0, 0,  0, "no" },
150
	{  0, 0,  0, "none" },
151
	{  1, 0,  0, "xor" },
152
	{  3, 1, 16, "twofish" },
153
	{  4, 1, 16, "blowfish" },
154
	{  7, 1, 16, "serpent" },
155
	{  8, 1, 16, "mars" },
156
	{ 11, 3, 16, "rc6" },
157
	{ 12, 0, 21, "tripleDES" },
158
	{ 12, 0, 24, "3des" },
159
	{ 12, 0, 24, "des3_ede" },
160
	{ 16, 1, 16, "AES" },
161
	{ -1, 0,  0, NULL }
162
};
163
164
static char *getApiName(char *e, int *len)
165
{
166
	int x, y, z = 1, q = -1;
167
	unsigned char *s;
168
169
	*len = y = 0;
170
	s = strdup(e);
171
	if(!s)
172
		return "";
173
	x = strlen(s);
174
	while(x > 0) {
175
		x--;
176
		if(!isdigit(s[x]))
177
			break;
178
		y += (s[x] - '0') * z;
179
		z *= 10;
180
		q = x;
181
	}
182
	while(x >= 0) {
183
		s[x] = tolower(s[x]);
184
		if(s[x] == '-')
185
			s[x] = 0;
186
		x--;
187
	}
188
	if(y >= 40) {
189
		if(q >= 0)
190
			s[q] = 0;
191
		*len = y;
192
	}
193
	return(s);
194
}
195
196
int loop_crypt_type(const char *name, u_int32_t *kbyp, char **apiName)
197
{
198
	int i, k;
199
200
	*apiName = getApiName((char *)name, &k);
201
	if(k < 0)
202
		k = 0;
203
	if(k > 256)
204
		k = 256;
205
	for (i = 0; loop_crypt_type_tbl[i].id != -1; i++) {
206
		if (!strcasecmp (*apiName , loop_crypt_type_tbl[i].name)) {
207
			*kbyp = k ? k >> 3 : loop_crypt_type_tbl[i].keyBytes;
208
			return loop_crypt_type_tbl[i].id;
209
		}
210
	}
211
	*kbyp = 16; /* 128 bits */
212
	return 18; /* LO_CRYPT_CRYPTOAPI */
213
}
214
215
int try_cryptoapi_loop_interface(int fd, struct loop_info64 *loopinfo, char *apiName)
216
{
217
	snprintf(loopinfo->lo_crypt_name, sizeof(loopinfo->lo_crypt_name), "%s-cbc", apiName);
218
	loopinfo->lo_crypt_name[LO_NAME_SIZE - 1] = 0;
219
	loopinfo->lo_encrypt_type = 18; /* LO_CRYPT_CRYPTOAPI */
220
	return(loop_set_status64_ioctl(fd, loopinfo));
221
}
(-)util-linux-2.12/mount/loop.h (-26 / +60 lines)
Lines 1-6 Link Here
1
#define LO_CRYPT_NONE	0
1
/*
2
#define LO_CRYPT_XOR	1
2
 *  loop.h
3
#define LO_CRYPT_DES	2
3
 *
4
 *  Copyright 2003 by Jari Ruusu.
5
 *  Redistribution of this file is permitted under the GNU GPL
6
 */
7
8
#ifndef _LOOP_H
9
#define _LOOP_H 1
10
11
#include <sys/types.h>
12
#include <linux/version.h>
13
#include <linux/posix_types.h>
14
15
#define LO_CRYPT_NONE   0
16
#define LO_CRYPT_XOR    1
17
#define LO_CRYPT_DES    2
4
#define LO_CRYPT_CRYPTOAPI 18
18
#define LO_CRYPT_CRYPTOAPI 18
5
19
6
#define LOOP_SET_FD		0x4C00
20
#define LOOP_SET_FD		0x4C00
Lines 9-25 Link Here
9
#define LOOP_GET_STATUS		0x4C03
23
#define LOOP_GET_STATUS		0x4C03
10
#define LOOP_SET_STATUS64	0x4C04
24
#define LOOP_SET_STATUS64	0x4C04
11
#define LOOP_GET_STATUS64	0x4C05
25
#define LOOP_GET_STATUS64	0x4C05
26
#define LOOP_MULTI_KEY_SETUP 	0x4C4D
12
27
13
#define LO_NAME_SIZE	64
28
#define LO_NAME_SIZE    64
14
#define LO_KEY_SIZE	32
29
#define LO_KEY_SIZE     32
15
16
#include "my_dev_t.h"
17
30
18
struct loop_info {
31
struct loop_info {
19
	int		lo_number;
32
	int		lo_number;
20
	my_dev_t	lo_device;
33
#if LINUX_VERSION_CODE >= 0x20600
34
	__kernel_old_dev_t lo_device;
35
#else
36
	__kernel_dev_t	lo_device;
37
#endif
21
	unsigned long	lo_inode;
38
	unsigned long	lo_inode;
22
	my_dev_t	lo_rdevice;
39
#if LINUX_VERSION_CODE >= 0x20600
40
	__kernel_old_dev_t lo_rdevice;
41
#else
42
	__kernel_dev_t	lo_rdevice;
43
#endif
23
	int		lo_offset;
44
	int		lo_offset;
24
	int		lo_encrypt_type;
45
	int		lo_encrypt_type;
25
	int		lo_encrypt_key_size;
46
	int		lo_encrypt_key_size;
Lines 30-51 Link Here
30
	char		reserved[4];
51
	char		reserved[4];
31
};
52
};
32
53
33
/*
34
 * Where to get __u8, __u32, __u64? Let us use unsigned char/int/long long
35
 * and get punished when someone comes with 128-bit long longs.
36
 */
37
struct loop_info64 {
54
struct loop_info64 {
38
	unsigned long long	lo_device;
55
	u_int64_t	lo_device; 		/* ioctl r/o */
39
	unsigned long long	lo_inode;
56
	u_int64_t	lo_inode; 		/* ioctl r/o */
40
	unsigned long long	lo_rdevice;
57
	u_int64_t	lo_rdevice; 		/* ioctl r/o */
41
	unsigned long long	lo_offset;
58
	u_int64_t	lo_offset;		/* bytes */
42
	unsigned long long	lo_sizelimit; /* bytes, 0 == max available */
59
	u_int64_t	lo_sizelimit;		/* bytes, 0 == max available */
43
	unsigned int		lo_number;
60
	u_int32_t	lo_number;		/* ioctl r/o */
44
	unsigned int		lo_encrypt_type;
61
	u_int32_t	lo_encrypt_type;
45
	unsigned int		lo_encrypt_key_size;
62
	u_int32_t	lo_encrypt_key_size; 	/* ioctl w/o */
46
	unsigned int		lo_flags;
63
	u_int32_t	lo_flags;		/* ioctl r/o */
47
	unsigned char		lo_file_name[LO_NAME_SIZE];
64
	unsigned char	lo_file_name[LO_NAME_SIZE];
48
	unsigned char		lo_crypt_name[LO_NAME_SIZE];
65
	unsigned char	lo_crypt_name[LO_NAME_SIZE];
49
	unsigned char		lo_encrypt_key[LO_KEY_SIZE];
66
	unsigned char	lo_encrypt_key[LO_KEY_SIZE]; /* ioctl w/o */
50
	unsigned long long	lo_init[2];
67
	u_int64_t	lo_init[2];
68
};
69
70
extern int loop_set_status64_ioctl(int, struct loop_info64 *);
71
extern int loop_get_status64_ioctl(int, struct loop_info64 *);
72
extern int is_unused_loop_device(int);
73
74
struct loop_crypt_type_struct {
75
	short int id;
76
	unsigned char flags; /* bit0 = show keybits, bit1 = add '-' before keybits */
77
	unsigned char keyBytes;
78
	char *name;
51
};
79
};
80
81
extern struct loop_crypt_type_struct loop_crypt_type_tbl[];
82
extern int loop_crypt_type(const char *, u_int32_t *, char **);
83
extern int try_cryptoapi_loop_interface(int, struct loop_info64 *, char *);
84
85
#endif
(-)util-linux-2.12/mount/losetup.8 (-72 / +108 lines)
Lines 1-26 Link Here
1
.TH LOSETUP 8 "2003-07-01" "Linux" "MAINTENANCE COMMANDS"
1
.TH LOSETUP 8 "2003-11-21" "Linux" "MAINTENANCE COMMANDS"
2
.SH NAME
2
.SH NAME
3
losetup \- set up and control loop devices
3
losetup \- set up and control loop devices
4
.SH SYNOPSIS
4
.SH SYNOPSIS
5
.ad l
5
.ad l
6
.B losetup
6
.B losetup
7
[
7
[
8
.RB [ \-e | \-E ]
8
.B \-e
9
.I encryption
9
.I encryption
10
] [
10
] [options]
11
.B \-o
11
.I loop_device
12
.I offset
12
file
13
] [
13
.br
14
.B \-p
14
.B losetup -F
15
.I pfd
15
[options]
16
]
16
.I loop_device
17
.I loop_device file
17
[file]
18
.br
18
.br
19
.B losetup
19
.B losetup
20
[
20
[
21
.B \-d
21
.B \-d
22
]
22
]
23
.I loop_device
23
.I loop_device
24
.br
25
.B losetup -a
24
.ad b
26
.ad b
25
.SH DESCRIPTION
27
.SH DESCRIPTION
26
.B losetup
28
.B losetup
Lines 28-68 Link Here
28
to detach loop devices and to query the status of a loop device. If only the
30
to detach loop devices and to query the status of a loop device. If only the
29
\fIloop_device\fP argument is given, the status of the corresponding loop
31
\fIloop_device\fP argument is given, the status of the corresponding loop
30
device is shown.
32
device is shown.
31
32
.SS "Encryption"
33
It is possible to specify transfer functions (for encryption/decryption
34
or other purposes) using one of the
35
.B \-E
36
and
37
.B \-e
38
options.
39
There are two mechanisms to specify the desired encryption: by number
40
and by name. If an encryption is specified by number then one
41
has to make sure that the Linux kernel knows about the encryption with that
42
number, probably by patching the kernel. Standard numbers that are
43
always present are 0 (no encryption) and 1 (XOR encryption).
44
When the cryptoloop module is loaded (or compiled in), it uses number 18.
45
This cryptoloop module wil take the name of an arbitrary encryption type
46
and finds the module that knows how to perform that encryption.
47
(Thus, either one uses a number different from 18 with the
48
.B \-E
49
option, or one uses a name with the
50
.B \-e
51
option.)
52
.SH OPTIONS
33
.SH OPTIONS
53
.IP \fB\-d\fP
34
.IP \fB\-a\fP
35
Show status of all loop devices.
36
.IP "\fB\-C \fIitercountk\fP"
37
Runs hashed password through \fIitercountk\fP thousand iterations of AES-256
38
before using it for loop encryption. This consumes lots of CPU cycles at
39
loop setup/mount time but not thereafter. In combination with password seed
40
this slows down dictionary attacks. Iteration is not done in multi-key mode.
41
.IP "\fB\-d\fP"
54
Detach the file or device associated with the specified loop device.
42
Detach the file or device associated with the specified loop device.
55
.IP "\fB\-E \fIencryption_type\fP"
43
.IP "\fB\-e \fIencryption\fP"
56
Enable data encryption with specified number.
44
.RS
57
.IP "\fB\-e \fIencryption_name\fP"
45
Enable data encryption. Following encryption types are recognized:
58
Enable data encryption with specified name.
46
.IP \fBNONE\fP
47
Use no encryption (default).
48
.PD 0
49
.IP \fBXOR\fP
50
Use a simple XOR encryption.
51
.IP "\fBAES128 AES\fP"
52
Use 128 bit AES encryption. Password is hashed with SHA-256 by default.
53
.IP \fBAES192\fP
54
Use 192 bit AES encryption. Password is hashed with SHA-384 by default.
55
.IP \fBAES256\fP
56
Use 256 bit AES encryption. Password is hashed with SHA-512 by default.
57
58
.IP "\fBtwofish128 twofish160 twofish192 twofish256\fP"
59
.IP "\fBblowfish128 blowfish160 blowfish192 blowfish256\fP"
60
.IP "\fBserpent128 serpent192 serpent256 mars128 mars192\fP"
61
.IP "\fBmars256 rc6-128 rc6-192 rc6-256 tripleDES\fP"
62
These encryption types are available if they are enabled in kernel
63
configuration or corresponding modules have been loaded to kernel.
64
.PD
65
.RE
66
.IP "\fB\-F\fP"
67
Reads and uses mount options from /etc/fstab that match specified loop
68
device, including offset= sizelimit= encryption= pseed= phash= loinit=
69
gpgkey= gpghome= itercountk= and looped to device/file name. loop= option in
70
/etc/fstab must match specified loop device name. Command line options take
71
precedence in case of conflict.
72
.IP "\fB\-G \fIgpghome\fP"
73
Set gpg home directory to \fIgpghome\fP, so that gpg uses public/private
74
keys on \fIgpghome\fP directory. This is only used when gpgkey file needs to
75
be decrypted using public/private keys. If gpgkey file is encrypted with
76
symmetric cipher only, public/private keys are not required and this option
77
has no effect.
78
.IP "\fB\-H \fIphash\fP"
79
Uses \fIphash\fP function to hash password. Available hash functions are
80
sha256, sha384, sha512 and rmd160. unhashed1 and unhashed2 functions also
81
exist for compatibility with some ancient implementations.
82
.IP "\fB\-I \fIloinit\fP"
83
Passes a numeric value of \fIloinit\fP as a parameter to cipher transfer
84
function. Cipher transfer functions are free to interpret value as they
85
want.
86
.IP "\fB\-K \fIgpgkey\fP"
87
Password is piped to gpg so that gpg can decrypt file \fIgpgkey\fP which
88
contains the real keys that are used to encrypt loop device. If decryption
89
requires public/private keys and gpghome is not specified, all users use
90
their own gpg public/private keys to decrypt \fIgpgkey\fP. Decrypted
91
\fIgpgkey\fP should contain either 1 or 64 keys, each key at least 20
92
characters and separated by newline. If decrypted \fIgpgkey\fP contains 64
93
keys, then loop device is put to multi-key mode. In multi-key mode first key
94
is used for first sector, second key for second sector, and so on.
59
.IP "\fB\-o \fIoffset\fP"
95
.IP "\fB\-o \fIoffset\fP"
60
The data start is moved \fIoffset\fP bytes into the specified file or
96
The data start is moved \fIoffset\fP bytes into the specified file or
61
device.
97
device. Normally offset is included in IV (initialization vector)
62
.IP "\fB\-p \fInum\fP"
98
computations. If offset is prefixed with @ character, then offset is not
63
Read the passphrase from file descriptor with number
99
included in IV computations. @ prefix functionality may not be supported on
64
.I num
100
some older kernels and/or loop drivers.
65
instead of from the terminal.
101
.IP "\fB\-p \fIpasswdfd\fP"
102
Read the passphrase from file descriptor \fIpasswdfd\fP instead of the
103
terminal.
104
.IP "\fB\-r\fP"
105
Read-only mode.
106
.IP "\fB\-s \fIsizelimit\fP"
107
Size of loop device is limited to \fIsizelimit\fP bytes. If unspecified or
108
set to zero, loop device size is set to maximum available (file size minus
109
offset). This option may not be supported on some older kernels and/or loop
110
drivers.
111
.IP "\fB\-S \fIpseed\fP"
112
Sets encryption password seed \fIpseed\fP which is appended to user supplied
113
password before hashing. Using different seeds for different partitions
114
makes dictionary attacks slower but does not prevent them if user supplied
115
password is guessable. Seed is not used in multi-key mode.
116
.IP "\fB\-T\fP"
117
Asks password twice.
118
.IP "\fB\-v\fP"
119
Verbose mode.
66
.SH RETURN VALUE
120
.SH RETURN VALUE
67
.B losetup
121
.B losetup
68
returns 0 on success, nonzero on failure. When
122
returns 0 on success, nonzero on failure. When
Lines 74-116 Link Here
74
128
75
.SH FILES
129
.SH FILES
76
.nf
130
.nf
77
/dev/loop0, /dev/loop1, ...   loop devices (major=7)
131
/dev/loop0,/dev/loop1,...   loop devices (major=7)
78
.fi
132
.fi
79
.SH EXAMPLE
133
.SH EXAMPLE
80
If you are using the loadable module you must have the module loaded
81
first with the command
82
.IP
83
# insmod loop.o
84
.LP
85
Maybe also encryption modules are needed.
86
.IP
87
# insmod des.o
88
# insmod cryptoloop.o
89
.LP
90
The following commands can be used as an example of using the loop device.
134
The following commands can be used as an example of using the loop device.
91
.nf
135
.nf
92
.IP
136
.IP
93
# dd if=/dev/zero of=/file bs=1k count=100
137
dd if=/dev/zero of=/file bs=1k count=100
94
# losetup -e des /dev/loop0 /file
138
losetup -e AES128 /dev/loop0 /file
95
Password:
139
Password:
96
Init (up to 16 hex digits):
140
mkfs -t ext2 /dev/loop0 100
97
# mkfs -t ext2 /dev/loop0 100
141
mount -t ext2 /dev/loop0 /mnt
98
# mount -t ext2 /dev/loop0 /mnt
99
 ...
142
 ...
100
# umount /dev/loop0
143
umount /dev/loop0
101
# losetup -d /dev/loop0
144
losetup -d /dev/loop0
102
.fi
103
.LP
104
If you are using the loadable module you may remove the module with
105
the command
106
.IP
107
# rmmod loop
108
.LP
109
.fi
145
.fi
110
.SH RESTRICTION
146
.SH RESTRICTION
111
DES encryption is painfully slow. On the other hand, XOR is terribly weak.
147
XOR encryption is terribly weak.
112
.\" .SH AUTHORS
148
.SH AUTHORS
113
.\" .nf
149
.nf
114
.\" Original version: Theodore Ts'o <tytso@athena.mit.edu>
150
Original version: Theodore Ts'o <tytso@athena.mit.edu>
115
.\" Original DES by: Eric Young <eay@psych.psy.uq.oz.au>
151
AES support: Jari Ruusu
116
.\" .fi
152
.fi
(-)util-linux-2.12/mount/loumount.c (+60 lines)
Line 0 Link Here
1
/*
2
 *  loumount.c
3
 *
4
 *  This code was extracted to separate file from lomount.c so that umount
5
 *  program doesn't have to link with all loop related setup code
6
 */
7
8
#define LOOPMAJOR      7
9
10
#include <stdio.h>
11
#include <string.h>
12
#include <ctype.h>
13
#include <fcntl.h>
14
#include <errno.h>
15
#include <stdlib.h>
16
#include <unistd.h>
17
#include <pwd.h>
18
#include <sys/types.h>
19
#include <sys/ioctl.h>
20
#include <sys/stat.h>
21
#include <sys/mman.h>
22
#include <sys/sysmacros.h>
23
#include <sys/wait.h>
24
#include <fcntl.h>
25
#include <mntent.h>
26
#include <locale.h>
27
28
#include "loop.h"
29
#include "lomount.h"
30
#include "xstrncpy.h"
31
#include "nls.h"
32
33
int
34
is_loop_device (const char *device) {
35
	struct stat statbuf;
36
37
	return (stat(device, &statbuf) == 0 &&
38
		S_ISBLK(statbuf.st_mode) &&
39
		major(statbuf.st_rdev) == LOOPMAJOR);
40
}
41
42
int 
43
del_loop (const char *device) {
44
	int fd;
45
46
	if ((fd = open (device, O_RDONLY)) < 0) {
47
		int errsv = errno;
48
		fprintf(stderr, _("loop: can't delete device %s: %s\n"),
49
			device, strerror (errsv));
50
		return 1;
51
	}
52
	if (ioctl (fd, LOOP_CLR_FD, 0) < 0) {
53
		perror ("ioctl: LOOP_CLR_FD");
54
		return 1;
55
	}
56
	close (fd);
57
	if (verbose > 1)
58
		printf(_("del_loop(%s): success\n"), device);
59
	return 0;
60
}
(-)util-linux-2.12/mount/mount.8 (-9 / +13 lines)
Lines 39-45 Link Here
39
.\" 010725, Nikita Danilov <NikitaDanilov@Yahoo.COM>: reiserfs options
39
.\" 010725, Nikita Danilov <NikitaDanilov@Yahoo.COM>: reiserfs options
40
.\" 011124, Karl Eichwalder <ke@gnu.franken.de>: tmpfs options
40
.\" 011124, Karl Eichwalder <ke@gnu.franken.de>: tmpfs options
41
.\"
41
.\"
42
.TH MOUNT 8 "14 September 1997" "Linux 2.0" "Linux Programmer's Manual"
42
.TH MOUNT 8 "May 23 2001" "Linux 2.0" "Linux Programmer's Manual"
43
.SH NAME
43
.SH NAME
44
mount \- mount a file system
44
mount \- mount a file system
45
.SH SYNOPSIS
45
.SH SYNOPSIS
Lines 270-275 Link Here
270
.B \-v
270
.B \-v
271
Verbose mode.
271
Verbose mode.
272
.TP
272
.TP
273
.B \-p "\fIpasswdfd\fP"
274
If the mount requires a passphrase to be entered, read it from file
275
descriptor
276
.IR passwdfd\fP
277
instead of from the terminal.
278
.TP
273
.B \-a
279
.B \-a
274
Mount all filesystems (of the given types) mentioned in
280
Mount all filesystems (of the given types) mentioned in
275
.IR fstab .
281
.IR fstab .
Lines 315-326 Link Here
315
.I /etc
321
.I /etc
316
is on a read-only file system.
322
is on a read-only file system.
317
.TP
323
.TP
318
.BI \-p " num"
319
In case of a loop mount with encryption, read the passphrase from
320
file descriptor
321
.I num
322
instead of from the terminal.
323
.TP
324
.B \-s
324
.B \-s
325
Tolerate sloppy mount options rather than failing. This will ignore
325
Tolerate sloppy mount options rather than failing. This will ignore
326
mount options not supported by a filesystem type. Not all filesystems
326
mount options not supported by a filesystem type. Not all filesystems
Lines 1692-1701 Link Here
1692
.IR /tmp/fdimage ,
1692
.IR /tmp/fdimage ,
1693
and then mount this device on
1693
and then mount this device on
1694
.IR /mnt .
1694
.IR /mnt .
1695
This type of mount knows about three options, namely
1695
This type of mount knows about 10 options, namely
1696
.BR loop ", " offset " and " encryption ,
1696
.BR loop ", " offset ", " sizelimit ", " encryption ", " pseed ", " phash ", " loinit ", " gpgkey ", " gpghome " and " itercountk
1697
that are really options to
1697
that are really options to
1698
.BR losetup (8).
1698
.BR losetup (8).
1699
If the mount requires a passphrase, you will be prompted for one unless you
1700
specify a file descriptor to read from instead with the
1701
.BR \-p
1702
option.
1699
If no explicit loop device is mentioned
1703
If no explicit loop device is mentioned
1700
(but just an option `\fB\-o loop\fP' is given), then
1704
(but just an option `\fB\-o loop\fP' is given), then
1701
.B mount
1705
.B mount
(-)util-linux-2.12/mount/mount.c (-21 / +16 lines)
Lines 47-52 Link Here
47
#include <string.h>
47
#include <string.h>
48
#include <getopt.h>
48
#include <getopt.h>
49
#include <stdio.h>
49
#include <stdio.h>
50
#include <locale.h>
50
51
51
#include <pwd.h>
52
#include <pwd.h>
52
#include <grp.h>
53
#include <grp.h>
Lines 113-121 Link Here
113
/* True if ruid != euid.  */
114
/* True if ruid != euid.  */
114
static int suid = 0;
115
static int suid = 0;
115
116
116
/* Contains the fd to read the passphrase from, if any. */
117
static int pfd = -1;
118
119
/* Map from -o and fstab option strings to the flag argument to mount(2).  */
117
/* Map from -o and fstab option strings to the flag argument to mount(2).  */
120
struct opt_map {
118
struct opt_map {
121
  const char *opt;		/* option name */
119
  const char *opt;		/* option name */
Lines 194-200 Link Here
194
  { NULL,	0, 0, 0		}
192
  { NULL,	0, 0, 0		}
195
};
193
};
196
194
197
static char *opt_loopdev, *opt_vfstype, *opt_offset, *opt_encryption,
195
static char *opt_loopdev, *opt_vfstype,
198
  *opt_speed;
196
  *opt_speed;
199
197
200
static struct string_opt_map {
198
static struct string_opt_map {
Lines 204-211 Link Here
204
} string_opt_map[] = {
202
} string_opt_map[] = {
205
  { "loop=",	0, &opt_loopdev },
203
  { "loop=",	0, &opt_loopdev },
206
  { "vfs=",	1, &opt_vfstype },
204
  { "vfs=",	1, &opt_vfstype },
207
  { "offset=",	0, &opt_offset },
205
  { "pseed=",	1, &passSeedString },
208
  { "encryption=", 0, &opt_encryption },
206
  { "phash=",	0, &passHashFuncName },
207
  { "loinit=",	0, &loInitValue },
208
  { "gpgkey=",	0, &gpgKeyFile },
209
  { "gpghome=",	0, &gpgHomeDir },
210
  { "itercountk=", 1, &passIterThousands },
211
  { "offset=",	0, &loopOffsetBytes },
212
  { "sizelimit=", 0, &loopSizeBytes },
213
  { "encryption=", 0, &loopEncryptionType },
209
  { "speed=", 0, &opt_speed },
214
  { "speed=", 0, &opt_speed },
210
  { NULL, 0, NULL }
215
  { NULL, 0, NULL }
211
};
216
};
Lines 561-567 Link Here
561
static int
566
static int
562
loop_check(char **spec, char **type, int *flags,
567
loop_check(char **spec, char **type, int *flags,
563
	   int *loop, char **loopdev, char **loopfile) {
568
	   int *loop, char **loopdev, char **loopfile) {
564
  int looptype, offset;
569
  int looptype;
565
570
566
  /*
571
  /*
567
   * In the case of a loop mount, either type is of the form lo@/dev/loop5
572
   * In the case of a loop mount, either type is of the form lo@/dev/loop5
Lines 586-592 Link Here
586
      *type = opt_vfstype;
591
      *type = opt_vfstype;
587
  }
592
  }
588
593
589
  *loop = ((*flags & MS_LOOP) || *loopdev || opt_offset || opt_encryption);
594
  *loop = ((*flags & MS_LOOP) || *loopdev || loopOffsetBytes || loopSizeBytes || loopEncryptionType);
590
  *loopfile = *spec;
595
  *loopfile = *spec;
591
596
592
  if (*loop) {
597
  if (*loop) {
Lines 603-611 Link Here
603
	return EX_SYSERR;	/* no more loop devices */
608
	return EX_SYSERR;	/* no more loop devices */
604
      if (verbose)
609
      if (verbose)
605
	printf(_("mount: going to use the loop device %s\n"), *loopdev);
610
	printf(_("mount: going to use the loop device %s\n"), *loopdev);
606
      offset = opt_offset ? strtoul(opt_offset, NULL, 0) : 0;
611
      if (set_loop (*loopdev, *loopfile, &loopro)) {
607
      if (set_loop(*loopdev, *loopfile, offset,
608
		   opt_encryption, pfd, &loopro)) {
609
	if (verbose)
612
	if (verbose)
610
	  printf(_("mount: failed setting up loop device\n"));
613
	  printf(_("mount: failed setting up loop device\n"));
611
	return EX_FAIL;
614
	return EX_FAIL;
Lines 664-677 Link Here
664
}
667
}
665
668
666
static void
669
static void
667
set_pfd(char *s) {
668
	if (!isdigit(*s))
669
		die(EX_USAGE,
670
		    _("mount: argument to -p or --pass-fd must be a number"));
671
	pfd = atoi(optarg);
672
}
673
674
static void
675
cdrom_setspeed(char *spec) {
670
cdrom_setspeed(char *spec) {
676
#define CDROM_SELECT_SPEED      0x5322  /* Set the CD-ROM speed */
671
#define CDROM_SELECT_SPEED      0x5322  /* Set the CD-ROM speed */
677
    if (opt_speed) {
672
    if (opt_speed) {
Lines 1486-1493 Link Here
1486
			else
1481
			else
1487
				test_opts = xstrdup(optarg);
1482
				test_opts = xstrdup(optarg);
1488
			break;
1483
			break;
1489
		case 'p':		/* fd on which to read passwd */
1484
		case 'p':               /* read passphrase from given fd */
1490
			set_pfd(optarg);
1485
			passFDnumber = optarg;
1491
			break;
1486
			break;
1492
		case 'r':		/* mount readonly */
1487
		case 'r':		/* mount readonly */
1493
			readonly = 1;
1488
			readonly = 1;
(-)util-linux-2.12/mount/rmd160.c (+532 lines)
Line 0 Link Here
1
/* rmd160.c  -	RIPE-MD160
2
 *	Copyright (C) 1998 Free Software Foundation, Inc.
3
 */
4
5
/* This file was part of GnuPG. Modified for use within the Linux
6
 * mount utility by Marc Mutz <Marc@Mutz.com>. None of this code is
7
 * by myself. I just removed everything that you don't need when all
8
 * you want to do is to use rmd160_hash_buffer().
9
 * My comments are marked with (mm).  */
10
11
/* GnuPG is free software; you can redistribute it and/or modify
12
 * it under the terms of the GNU General Public License as published by
13
 * the Free Software Foundation; either version 2 of the License, or
14
 * (at your option) any later version.
15
 *
16
 * GnuPG is distributed in the hope that it will be useful,
17
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
 * GNU General Public License for more details.
20
 *
21
 * You should have received a copy of the GNU General Public License
22
 * along with this program; if not, write to the Free Software
23
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */
24
25
#include <string.h> /* (mm) for memcpy */
26
#include <endian.h> /* (mm) for BIG_ENDIAN and BYTE_ORDER */
27
#include "rmd160.h"
28
29
/* (mm) these are used by the original GnuPG file. In order to modify
30
 * that file not too much, we keep the notations. maybe it would be
31
 * better to include linux/types.h and typedef __u32 to u32 and __u8
32
 * to byte?  */
33
typedef unsigned int u32; /* taken from e.g. util-linux's minix.h */
34
typedef unsigned char byte;
35
36
typedef struct {
37
    u32  h0,h1,h2,h3,h4;
38
    u32  nblocks;
39
    byte buf[64];
40
    int  count;
41
} RMD160_CONTEXT;
42
43
/****************
44
 * Rotate a 32 bit integer by n bytes
45
 */
46
#if defined(__GNUC__) && defined(__i386__)
47
static inline u32
48
rol( u32 x, int n)
49
{
50
	__asm__("roll %%cl,%0"
51
		:"=r" (x)
52
		:"0" (x),"c" (n));
53
	return x;
54
}
55
#else
56
  #define rol(x,n) ( ((x) << (n)) | ((x) >> (32-(n))) )
57
#endif
58
59
/*********************************
60
 * RIPEMD-160 is not patented, see (as of 25.10.97)
61
 *   http://www.esat.kuleuven.ac.be/~bosselae/ripemd160.html
62
 * Note that the code uses Little Endian byteorder, which is good for
63
 * 386 etc, but we must add some conversion when used on a big endian box.
64
 *
65
 *
66
 * Pseudo-code for RIPEMD-160
67
 *
68
 * RIPEMD-160 is an iterative hash function that operates on 32-bit words.
69
 * The round function takes as input a 5-word chaining variable and a 16-word
70
 * message block and maps this to a new chaining variable. All operations are
71
 * defined on 32-bit words. Padding is identical to that of MD4.
72
 *
73
 *
74
 * RIPEMD-160: definitions
75
 *
76
 *
77
 *   nonlinear functions at bit level: exor, mux, -, mux, -
78
 *
79
 *   f(j, x, y, z) = x XOR y XOR z		  (0 <= j <= 15)
80
 *   f(j, x, y, z) = (x AND y) OR (NOT(x) AND z)  (16 <= j <= 31)
81
 *   f(j, x, y, z) = (x OR NOT(y)) XOR z	  (32 <= j <= 47)
82
 *   f(j, x, y, z) = (x AND z) OR (y AND NOT(z))  (48 <= j <= 63)
83
 *   f(j, x, y, z) = x XOR (y OR NOT(z))	  (64 <= j <= 79)
84
 *
85
 *
86
 *   added constants (hexadecimal)
87
 *
88
 *   K(j) = 0x00000000	    (0 <= j <= 15)
89
 *   K(j) = 0x5A827999	   (16 <= j <= 31)	int(2**30 x sqrt(2))
90
 *   K(j) = 0x6ED9EBA1	   (32 <= j <= 47)	int(2**30 x sqrt(3))
91
 *   K(j) = 0x8F1BBCDC	   (48 <= j <= 63)	int(2**30 x sqrt(5))
92
 *   K(j) = 0xA953FD4E	   (64 <= j <= 79)	int(2**30 x sqrt(7))
93
 *   K'(j) = 0x50A28BE6     (0 <= j <= 15)      int(2**30 x cbrt(2))
94
 *   K'(j) = 0x5C4DD124    (16 <= j <= 31)      int(2**30 x cbrt(3))
95
 *   K'(j) = 0x6D703EF3    (32 <= j <= 47)      int(2**30 x cbrt(5))
96
 *   K'(j) = 0x7A6D76E9    (48 <= j <= 63)      int(2**30 x cbrt(7))
97
 *   K'(j) = 0x00000000    (64 <= j <= 79)
98
 *
99
 *
100
 *   selection of message word
101
 *
102
 *   r(j)      = j		      (0 <= j <= 15)
103
 *   r(16..31) = 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8
104
 *   r(32..47) = 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12
105
 *   r(48..63) = 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2
106
 *   r(64..79) = 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13
107
 *   r0(0..15) = 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12
108
 *   r0(16..31)= 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2
109
 *   r0(32..47)= 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13
110
 *   r0(48..63)= 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14
111
 *   r0(64..79)= 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11
112
 *
113
 *
114
 *   amount for rotate left (rol)
115
 *
116
 *   s(0..15)  = 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8
117
 *   s(16..31) = 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12
118
 *   s(32..47) = 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5
119
 *   s(48..63) = 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12
120
 *   s(64..79) = 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6
121
 *   s'(0..15) = 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6
122
 *   s'(16..31)= 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11
123
 *   s'(32..47)= 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5
124
 *   s'(48..63)= 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8
125
 *   s'(64..79)= 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11
126
 *
127
 *
128
 *   initial value (hexadecimal)
129
 *
130
 *   h0 = 0x67452301; h1 = 0xEFCDAB89; h2 = 0x98BADCFE; h3 = 0x10325476;
131
 *							h4 = 0xC3D2E1F0;
132
 *
133
 *
134
 * RIPEMD-160: pseudo-code
135
 *
136
 *   It is assumed that the message after padding consists of t 16-word blocks
137
 *   that will be denoted with X[i][j], with 0 <= i <= t-1 and 0 <= j <= 15.
138
 *   The symbol [+] denotes addition modulo 2**32 and rol_s denotes cyclic left
139
 *   shift (rotate) over s positions.
140
 *
141
 *
142
 *   for i := 0 to t-1 {
143
 *	 A := h0; B := h1; C := h2; D = h3; E = h4;
144
 *	 A' := h0; B' := h1; C' := h2; D' = h3; E' = h4;
145
 *	 for j := 0 to 79 {
146
 *	     T := rol_s(j)(A [+] f(j, B, C, D) [+] X[i][r(j)] [+] K(j)) [+] E;
147
 *	     A := E; E := D; D := rol_10(C); C := B; B := T;
148
 *	     T := rol_s'(j)(A' [+] f(79-j, B', C', D') [+] X[i][r'(j)]
149
						       [+] K'(j)) [+] E';
150
 *	     A' := E'; E' := D'; D' := rol_10(C'); C' := B'; B' := T;
151
 *	 }
152
 *	 T := h1 [+] C [+] D'; h1 := h2 [+] D [+] E'; h2 := h3 [+] E [+] A';
153
 *	 h3 := h4 [+] A [+] B'; h4 := h0 [+] B [+] C'; h0 := T;
154
 *   }
155
 */
156
157
/* Some examples:
158
 * ""                    9c1185a5c5e9fc54612808977ee8f548b2258d31
159
 * "a"                   0bdc9d2d256b3ee9daae347be6f4dc835a467ffe
160
 * "abc"                 8eb208f7e05d987a9b044a8e98c6b087f15a0bfc
161
 * "message digest"      5d0689ef49d2fae572b881b123a85ffa21595f36
162
 * "a...z"               f71c27109c692c1b56bbdceb5b9d2865b3708dbc
163
 * "abcdbcde...nopq"     12a053384a9c0c88e405a06c27dcf49ada62eb2b
164
 * "A...Za...z0...9"     b0e20b6e3116640286ed3a87a5713079b21f5189
165
 * 8 times "1234567890"  9b752e45573d4b39f4dbd3323cab82bf63326bfb
166
 * 1 million times "a"   52783243c1697bdbe16d37f97f68f08325dc1528
167
 */
168
169
170
static void
171
rmd160_init( RMD160_CONTEXT *hd )
172
{
173
    hd->h0 = 0x67452301;
174
    hd->h1 = 0xEFCDAB89;
175
    hd->h2 = 0x98BADCFE;
176
    hd->h3 = 0x10325476;
177
    hd->h4 = 0xC3D2E1F0;
178
    hd->nblocks = 0;
179
    hd->count = 0;
180
}
181
182
183
184
/****************
185
 * Transform the message X which consists of 16 32-bit-words
186
 */
187
static void
188
transform( RMD160_CONTEXT *hd, byte *data )
189
{
190
    u32 a,b,c,d,e,aa,bb,cc,dd,ee,t;
191
  #if BYTE_ORDER == BIG_ENDIAN
192
    u32 x[16];
193
    { int i;
194
      byte *p2, *p1;
195
      for(i=0, p1=data, p2=(byte*)x; i < 16; i++, p2 += 4 ) {
196
	p2[3] = *p1++;
197
	p2[2] = *p1++;
198
	p2[1] = *p1++;
199
	p2[0] = *p1++;
200
      }
201
    }
202
  #else
203
   #if 0
204
    u32 *x =(u32*)data;
205
   #else
206
    /* this version is better because it is always aligned;
207
     * The performance penalty on a 586-100 is about 6% which
208
     * is acceptable - because the data is more local it might
209
     * also be possible that this is faster on some machines.
210
     * This function (when compiled with -02 on gcc 2.7.2)
211
     * executes on a 586-100 (39.73 bogomips) at about 1900kb/sec;
212
     * [measured with a 4MB data and "gpgm --print-md rmd160"] */
213
    u32 x[16];
214
    memcpy( x, data, 64 );
215
   #endif
216
  #endif
217
218
219
#define K0  0x00000000
220
#define K1  0x5A827999
221
#define K2  0x6ED9EBA1
222
#define K3  0x8F1BBCDC
223
#define K4  0xA953FD4E
224
#define KK0 0x50A28BE6
225
#define KK1 0x5C4DD124
226
#define KK2 0x6D703EF3
227
#define KK3 0x7A6D76E9
228
#define KK4 0x00000000
229
#define F0(x,y,z)   ( (x) ^ (y) ^ (z) )
230
#define F1(x,y,z)   ( ((x) & (y)) | (~(x) & (z)) )
231
#define F2(x,y,z)   ( ((x) | ~(y)) ^ (z) )
232
#define F3(x,y,z)   ( ((x) & (z)) | ((y) & ~(z)) )
233
#define F4(x,y,z)   ( (x) ^ ((y) | ~(z)) )
234
#define R(a,b,c,d,e,f,k,r,s) do { t = a + f(b,c,d) + k + x[r]; \
235
				  a = rol(t,s) + e;	       \
236
				  c = rol(c,10);	       \
237
				} while(0)
238
239
    /* left lane */
240
    a = hd->h0;
241
    b = hd->h1;
242
    c = hd->h2;
243
    d = hd->h3;
244
    e = hd->h4;
245
    R( a, b, c, d, e, F0, K0,  0, 11 );
246
    R( e, a, b, c, d, F0, K0,  1, 14 );
247
    R( d, e, a, b, c, F0, K0,  2, 15 );
248
    R( c, d, e, a, b, F0, K0,  3, 12 );
249
    R( b, c, d, e, a, F0, K0,  4,  5 );
250
    R( a, b, c, d, e, F0, K0,  5,  8 );
251
    R( e, a, b, c, d, F0, K0,  6,  7 );
252
    R( d, e, a, b, c, F0, K0,  7,  9 );
253
    R( c, d, e, a, b, F0, K0,  8, 11 );
254
    R( b, c, d, e, a, F0, K0,  9, 13 );
255
    R( a, b, c, d, e, F0, K0, 10, 14 );
256
    R( e, a, b, c, d, F0, K0, 11, 15 );
257
    R( d, e, a, b, c, F0, K0, 12,  6 );
258
    R( c, d, e, a, b, F0, K0, 13,  7 );
259
    R( b, c, d, e, a, F0, K0, 14,  9 );
260
    R( a, b, c, d, e, F0, K0, 15,  8 );
261
    R( e, a, b, c, d, F1, K1,  7,  7 );
262
    R( d, e, a, b, c, F1, K1,  4,  6 );
263
    R( c, d, e, a, b, F1, K1, 13,  8 );
264
    R( b, c, d, e, a, F1, K1,  1, 13 );
265
    R( a, b, c, d, e, F1, K1, 10, 11 );
266
    R( e, a, b, c, d, F1, K1,  6,  9 );
267
    R( d, e, a, b, c, F1, K1, 15,  7 );
268
    R( c, d, e, a, b, F1, K1,  3, 15 );
269
    R( b, c, d, e, a, F1, K1, 12,  7 );
270
    R( a, b, c, d, e, F1, K1,  0, 12 );
271
    R( e, a, b, c, d, F1, K1,  9, 15 );
272
    R( d, e, a, b, c, F1, K1,  5,  9 );
273
    R( c, d, e, a, b, F1, K1,  2, 11 );
274
    R( b, c, d, e, a, F1, K1, 14,  7 );
275
    R( a, b, c, d, e, F1, K1, 11, 13 );
276
    R( e, a, b, c, d, F1, K1,  8, 12 );
277
    R( d, e, a, b, c, F2, K2,  3, 11 );
278
    R( c, d, e, a, b, F2, K2, 10, 13 );
279
    R( b, c, d, e, a, F2, K2, 14,  6 );
280
    R( a, b, c, d, e, F2, K2,  4,  7 );
281
    R( e, a, b, c, d, F2, K2,  9, 14 );
282
    R( d, e, a, b, c, F2, K2, 15,  9 );
283
    R( c, d, e, a, b, F2, K2,  8, 13 );
284
    R( b, c, d, e, a, F2, K2,  1, 15 );
285
    R( a, b, c, d, e, F2, K2,  2, 14 );
286
    R( e, a, b, c, d, F2, K2,  7,  8 );
287
    R( d, e, a, b, c, F2, K2,  0, 13 );
288
    R( c, d, e, a, b, F2, K2,  6,  6 );
289
    R( b, c, d, e, a, F2, K2, 13,  5 );
290
    R( a, b, c, d, e, F2, K2, 11, 12 );
291
    R( e, a, b, c, d, F2, K2,  5,  7 );
292
    R( d, e, a, b, c, F2, K2, 12,  5 );
293
    R( c, d, e, a, b, F3, K3,  1, 11 );
294
    R( b, c, d, e, a, F3, K3,  9, 12 );
295
    R( a, b, c, d, e, F3, K3, 11, 14 );
296
    R( e, a, b, c, d, F3, K3, 10, 15 );
297
    R( d, e, a, b, c, F3, K3,  0, 14 );
298
    R( c, d, e, a, b, F3, K3,  8, 15 );
299
    R( b, c, d, e, a, F3, K3, 12,  9 );
300
    R( a, b, c, d, e, F3, K3,  4,  8 );
301
    R( e, a, b, c, d, F3, K3, 13,  9 );
302
    R( d, e, a, b, c, F3, K3,  3, 14 );
303
    R( c, d, e, a, b, F3, K3,  7,  5 );
304
    R( b, c, d, e, a, F3, K3, 15,  6 );
305
    R( a, b, c, d, e, F3, K3, 14,  8 );
306
    R( e, a, b, c, d, F3, K3,  5,  6 );
307
    R( d, e, a, b, c, F3, K3,  6,  5 );
308
    R( c, d, e, a, b, F3, K3,  2, 12 );
309
    R( b, c, d, e, a, F4, K4,  4,  9 );
310
    R( a, b, c, d, e, F4, K4,  0, 15 );
311
    R( e, a, b, c, d, F4, K4,  5,  5 );
312
    R( d, e, a, b, c, F4, K4,  9, 11 );
313
    R( c, d, e, a, b, F4, K4,  7,  6 );
314
    R( b, c, d, e, a, F4, K4, 12,  8 );
315
    R( a, b, c, d, e, F4, K4,  2, 13 );
316
    R( e, a, b, c, d, F4, K4, 10, 12 );
317
    R( d, e, a, b, c, F4, K4, 14,  5 );
318
    R( c, d, e, a, b, F4, K4,  1, 12 );
319
    R( b, c, d, e, a, F4, K4,  3, 13 );
320
    R( a, b, c, d, e, F4, K4,  8, 14 );
321
    R( e, a, b, c, d, F4, K4, 11, 11 );
322
    R( d, e, a, b, c, F4, K4,  6,  8 );
323
    R( c, d, e, a, b, F4, K4, 15,  5 );
324
    R( b, c, d, e, a, F4, K4, 13,  6 );
325
326
    aa = a; bb = b; cc = c; dd = d; ee = e;
327
328
    /* right lane */
329
    a = hd->h0;
330
    b = hd->h1;
331
    c = hd->h2;
332
    d = hd->h3;
333
    e = hd->h4;
334
    R( a, b, c, d, e, F4, KK0,	5,  8);
335
    R( e, a, b, c, d, F4, KK0, 14,  9);
336
    R( d, e, a, b, c, F4, KK0,	7,  9);
337
    R( c, d, e, a, b, F4, KK0,	0, 11);
338
    R( b, c, d, e, a, F4, KK0,	9, 13);
339
    R( a, b, c, d, e, F4, KK0,	2, 15);
340
    R( e, a, b, c, d, F4, KK0, 11, 15);
341
    R( d, e, a, b, c, F4, KK0,	4,  5);
342
    R( c, d, e, a, b, F4, KK0, 13,  7);
343
    R( b, c, d, e, a, F4, KK0,	6,  7);
344
    R( a, b, c, d, e, F4, KK0, 15,  8);
345
    R( e, a, b, c, d, F4, KK0,	8, 11);
346
    R( d, e, a, b, c, F4, KK0,	1, 14);
347
    R( c, d, e, a, b, F4, KK0, 10, 14);
348
    R( b, c, d, e, a, F4, KK0,	3, 12);
349
    R( a, b, c, d, e, F4, KK0, 12,  6);
350
    R( e, a, b, c, d, F3, KK1,	6,  9);
351
    R( d, e, a, b, c, F3, KK1, 11, 13);
352
    R( c, d, e, a, b, F3, KK1,	3, 15);
353
    R( b, c, d, e, a, F3, KK1,	7,  7);
354
    R( a, b, c, d, e, F3, KK1,	0, 12);
355
    R( e, a, b, c, d, F3, KK1, 13,  8);
356
    R( d, e, a, b, c, F3, KK1,	5,  9);
357
    R( c, d, e, a, b, F3, KK1, 10, 11);
358
    R( b, c, d, e, a, F3, KK1, 14,  7);
359
    R( a, b, c, d, e, F3, KK1, 15,  7);
360
    R( e, a, b, c, d, F3, KK1,	8, 12);
361
    R( d, e, a, b, c, F3, KK1, 12,  7);
362
    R( c, d, e, a, b, F3, KK1,	4,  6);
363
    R( b, c, d, e, a, F3, KK1,	9, 15);
364
    R( a, b, c, d, e, F3, KK1,	1, 13);
365
    R( e, a, b, c, d, F3, KK1,	2, 11);
366
    R( d, e, a, b, c, F2, KK2, 15,  9);
367
    R( c, d, e, a, b, F2, KK2,	5,  7);
368
    R( b, c, d, e, a, F2, KK2,	1, 15);
369
    R( a, b, c, d, e, F2, KK2,	3, 11);
370
    R( e, a, b, c, d, F2, KK2,	7,  8);
371
    R( d, e, a, b, c, F2, KK2, 14,  6);
372
    R( c, d, e, a, b, F2, KK2,	6,  6);
373
    R( b, c, d, e, a, F2, KK2,	9, 14);
374
    R( a, b, c, d, e, F2, KK2, 11, 12);
375
    R( e, a, b, c, d, F2, KK2,	8, 13);
376
    R( d, e, a, b, c, F2, KK2, 12,  5);
377
    R( c, d, e, a, b, F2, KK2,	2, 14);
378
    R( b, c, d, e, a, F2, KK2, 10, 13);
379
    R( a, b, c, d, e, F2, KK2,	0, 13);
380
    R( e, a, b, c, d, F2, KK2,	4,  7);
381
    R( d, e, a, b, c, F2, KK2, 13,  5);
382
    R( c, d, e, a, b, F1, KK3,	8, 15);
383
    R( b, c, d, e, a, F1, KK3,	6,  5);
384
    R( a, b, c, d, e, F1, KK3,	4,  8);
385
    R( e, a, b, c, d, F1, KK3,	1, 11);
386
    R( d, e, a, b, c, F1, KK3,	3, 14);
387
    R( c, d, e, a, b, F1, KK3, 11, 14);
388
    R( b, c, d, e, a, F1, KK3, 15,  6);
389
    R( a, b, c, d, e, F1, KK3,	0, 14);
390
    R( e, a, b, c, d, F1, KK3,	5,  6);
391
    R( d, e, a, b, c, F1, KK3, 12,  9);
392
    R( c, d, e, a, b, F1, KK3,	2, 12);
393
    R( b, c, d, e, a, F1, KK3, 13,  9);
394
    R( a, b, c, d, e, F1, KK3,	9, 12);
395
    R( e, a, b, c, d, F1, KK3,	7,  5);
396
    R( d, e, a, b, c, F1, KK3, 10, 15);
397
    R( c, d, e, a, b, F1, KK3, 14,  8);
398
    R( b, c, d, e, a, F0, KK4, 12,  8);
399
    R( a, b, c, d, e, F0, KK4, 15,  5);
400
    R( e, a, b, c, d, F0, KK4, 10, 12);
401
    R( d, e, a, b, c, F0, KK4,	4,  9);
402
    R( c, d, e, a, b, F0, KK4,	1, 12);
403
    R( b, c, d, e, a, F0, KK4,	5,  5);
404
    R( a, b, c, d, e, F0, KK4,	8, 14);
405
    R( e, a, b, c, d, F0, KK4,	7,  6);
406
    R( d, e, a, b, c, F0, KK4,	6,  8);
407
    R( c, d, e, a, b, F0, KK4,	2, 13);
408
    R( b, c, d, e, a, F0, KK4, 13,  6);
409
    R( a, b, c, d, e, F0, KK4, 14,  5);
410
    R( e, a, b, c, d, F0, KK4,	0, 15);
411
    R( d, e, a, b, c, F0, KK4,	3, 13);
412
    R( c, d, e, a, b, F0, KK4,	9, 11);
413
    R( b, c, d, e, a, F0, KK4, 11, 11);
414
415
416
    t	   = hd->h1 + d + cc;
417
    hd->h1 = hd->h2 + e + dd;
418
    hd->h2 = hd->h3 + a + ee;
419
    hd->h3 = hd->h4 + b + aa;
420
    hd->h4 = hd->h0 + c + bb;
421
    hd->h0 = t;
422
}
423
424
425
/* Update the message digest with the contents
426
 * of INBUF with length INLEN.
427
 */
428
static void
429
rmd160_write( RMD160_CONTEXT *hd, byte *inbuf, size_t inlen)
430
{
431
    if( hd->count == 64 ) { /* flush the buffer */
432
	transform( hd, hd->buf );
433
	hd->count = 0;
434
	hd->nblocks++;
435
    }
436
    if( !inbuf )
437
	return;
438
    if( hd->count ) {
439
	for( ; inlen && hd->count < 64; inlen-- )
440
	    hd->buf[hd->count++] = *inbuf++;
441
	rmd160_write( hd, NULL, 0 );
442
	if( !inlen )
443
	    return;
444
    }
445
446
    while( inlen >= 64 ) {
447
	transform( hd, inbuf );
448
	hd->count = 0;
449
	hd->nblocks++;
450
	inlen -= 64;
451
	inbuf += 64;
452
    }
453
    for( ; inlen && hd->count < 64; inlen-- )
454
	hd->buf[hd->count++] = *inbuf++;
455
}
456
457
/* The routine terminates the computation
458
 */
459
460
static void
461
rmd160_final( RMD160_CONTEXT *hd )
462
{
463
    u32 t, msb, lsb;
464
    byte *p;
465
466
    rmd160_write(hd, NULL, 0); /* flush */;
467
468
    msb = 0;
469
    t = hd->nblocks;
470
    if( (lsb = t << 6) < t ) /* multiply by 64 to make a byte count */
471
	msb++;
472
    msb += t >> 26;
473
    t = lsb;
474
    if( (lsb = t + hd->count) < t ) /* add the count */
475
	msb++;
476
    t = lsb;
477
    if( (lsb = t << 3) < t ) /* multiply by 8 to make a bit count */
478
	msb++;
479
    msb += t >> 29;
480
481
    if( hd->count < 56 ) { /* enough room */
482
	hd->buf[hd->count++] = 0x80; /* pad */
483
	while( hd->count < 56 )
484
	    hd->buf[hd->count++] = 0;  /* pad */
485
    }
486
    else { /* need one extra block */
487
	hd->buf[hd->count++] = 0x80; /* pad character */
488
	while( hd->count < 64 )
489
	    hd->buf[hd->count++] = 0;
490
	rmd160_write(hd, NULL, 0);  /* flush */;
491
	memset(hd->buf, 0, 56 ); /* fill next block with zeroes */
492
    }
493
    /* append the 64 bit count */
494
    hd->buf[56] = lsb	   ;
495
    hd->buf[57] = lsb >>  8;
496
    hd->buf[58] = lsb >> 16;
497
    hd->buf[59] = lsb >> 24;
498
    hd->buf[60] = msb	   ;
499
    hd->buf[61] = msb >>  8;
500
    hd->buf[62] = msb >> 16;
501
    hd->buf[63] = msb >> 24;
502
    transform( hd, hd->buf );
503
504
    p = hd->buf;
505
  #if BYTE_ORDER == BIG_ENDIAN
506
    #define X(a) do { *p++ = hd->h##a	   ; *p++ = hd->h##a >> 8;	\
507
		      *p++ = hd->h##a >> 16; *p++ = hd->h##a >> 24; } while(0)
508
  #else /* little endian */
509
    #define X(a) do { *(u32*)p = hd->h##a ; p += 4; } while(0)
510
  #endif
511
    X(0);
512
    X(1);
513
    X(2);
514
    X(3);
515
    X(4);
516
  #undef X
517
}
518
519
/****************
520
 * Shortcut functions which puts the hash value of the supplied buffer
521
 * into outbuf which must have a size of 20 bytes.
522
 */
523
void
524
rmd160_hash_buffer( char *outbuf, const char *buffer, size_t length )
525
{
526
    RMD160_CONTEXT hd;
527
528
    rmd160_init( &hd );
529
    rmd160_write( &hd, (byte*)buffer, length );
530
    rmd160_final( &hd );
531
    memcpy( outbuf, hd.buf, 20 );
532
}
(-)util-linux-2.12/mount/rmd160.h (+9 lines)
Line 0 Link Here
1
#ifndef RMD160_H
2
#define RMD160_H
3
4
void
5
rmd160_hash_buffer( char *outbuf, const char *buffer, size_t length );
6
7
#endif /*RMD160_H*/
8
9
(-)util-linux-2.12/mount/sha512.c (+432 lines)
Line 0 Link Here
1
/*
2
 *  sha512.c
3
 *
4
 *  Written by Jari Ruusu, April 16 2001
5
 *
6
 *  Copyright 2001 by Jari Ruusu.
7
 *  Redistribution of this file is permitted under the GNU Public License.
8
 */
9
10
#include <string.h>
11
#include <sys/types.h>
12
#include "sha512.h"
13
14
/* Define one or more of these. If none is defined, you get all of them */
15
#if !defined(SHA256_NEEDED)&&!defined(SHA512_NEEDED)&&!defined(SHA384_NEEDED)
16
# define SHA256_NEEDED  1
17
# define SHA512_NEEDED  1
18
# define SHA384_NEEDED  1
19
#endif
20
21
#if defined(SHA256_NEEDED)
22
static const u_int32_t sha256_hashInit[8] = {
23
    0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c,
24
    0x1f83d9ab, 0x5be0cd19
25
};
26
static const u_int32_t sha256_K[64] = {
27
    0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1,
28
    0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
29
    0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786,
30
    0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
31
    0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,
32
    0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
33
    0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b,
34
    0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
35
    0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a,
36
    0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
37
    0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
38
};
39
#endif
40
41
#if defined(SHA512_NEEDED)
42
static const u_int64_t sha512_hashInit[8] = {
43
    0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, 0x3c6ef372fe94f82bULL,
44
    0xa54ff53a5f1d36f1ULL, 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL,
45
    0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL
46
};
47
#endif
48
49
#if defined(SHA384_NEEDED)
50
static const u_int64_t sha384_hashInit[8] = {
51
    0xcbbb9d5dc1059ed8ULL, 0x629a292a367cd507ULL, 0x9159015a3070dd17ULL,
52
    0x152fecd8f70e5939ULL, 0x67332667ffc00b31ULL, 0x8eb44a8768581511ULL,
53
    0xdb0c2e0d64f98fa7ULL, 0x47b5481dbefa4fa4ULL
54
};
55
#endif
56
57
#if defined(SHA512_NEEDED) || defined(SHA384_NEEDED)
58
static const u_int64_t sha512_K[80] = {
59
    0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL,
60
    0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
61
    0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 0xd807aa98a3030242ULL,
62
    0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
63
    0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL,
64
    0xc19bf174cf692694ULL, 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
65
    0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, 0x2de92c6f592b0275ULL,
66
    0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
67
    0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL,
68
    0xbf597fc7beef0ee4ULL, 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
69
    0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 0x27b70a8546d22ffcULL,
70
    0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
71
    0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL,
72
    0x92722c851482353bULL, 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
73
    0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 0xd192e819d6ef5218ULL,
74
    0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
75
    0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL,
76
    0x34b0bcb5e19b48a8ULL, 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
77
    0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, 0x748f82ee5defb2fcULL,
78
    0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
79
    0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL,
80
    0xc67178f2e372532bULL, 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
81
    0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 0x06f067aa72176fbaULL,
82
    0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
83
    0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL,
84
    0x431d67c49c100d4cULL, 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
85
    0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
86
};
87
#endif
88
89
#define Ch(x,y,z)   (((x) & (y)) ^ ((~(x)) & (z)))
90
#define Maj(x,y,z)  (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
91
#define R(x,y)      ((y) >> (x))
92
93
#if defined(SHA256_NEEDED)
94
void sha256_init(sha256_context *ctx)
95
{
96
    memcpy(&ctx->sha_H[0], &sha256_hashInit[0], sizeof(ctx->sha_H));
97
    ctx->sha_blocks = 0;
98
    ctx->sha_bufCnt = 0;
99
}
100
101
#define S(x,y)      (((y) >> (x)) | ((y) << (32 - (x))))
102
#define uSig0(x)    ((S(2,(x))) ^ (S(13,(x))) ^ (S(22,(x))))
103
#define uSig1(x)    ((S(6,(x))) ^ (S(11,(x))) ^ (S(25,(x))))
104
#define lSig0(x)    ((S(7,(x))) ^ (S(18,(x))) ^ (R(3,(x))))
105
#define lSig1(x)    ((S(17,(x))) ^ (S(19,(x))) ^ (R(10,(x))))
106
107
static void sha256_transform(sha256_context *ctx, unsigned char *datap)
108
{
109
    register int    j;
110
    u_int32_t       a, b, c, d, e, f, g, h;
111
    u_int32_t       T1, T2, W[64], Wm2, Wm15;
112
113
    /* read the data, big endian byte order */
114
    j = 0;
115
    do {
116
        W[j] = (((u_int32_t)(datap[0]))<<24) | (((u_int32_t)(datap[1]))<<16) |
117
               (((u_int32_t)(datap[2]))<<8 ) | ((u_int32_t)(datap[3]));
118
        datap += 4;
119
    } while(++j < 16);
120
    
121
    /* initialize variables a...h */
122
    a = ctx->sha_H[0];
123
    b = ctx->sha_H[1];
124
    c = ctx->sha_H[2];
125
    d = ctx->sha_H[3];
126
    e = ctx->sha_H[4];
127
    f = ctx->sha_H[5];
128
    g = ctx->sha_H[6];
129
    h = ctx->sha_H[7];
130
131
    /* apply compression function */
132
    j = 0;
133
    do {
134
        if(j >= 16) {
135
            Wm2 = W[j - 2];
136
            Wm15 = W[j - 15];
137
            W[j] = lSig1(Wm2) + W[j - 7] + lSig0(Wm15) + W[j - 16];
138
        }
139
        T1 = h + uSig1(e) + Ch(e,f,g) + sha256_K[j] + W[j];
140
        T2 = uSig0(a) + Maj(a,b,c);
141
        h = g; g = f; f = e;
142
        e = d + T1;
143
        d = c; c = b; b = a;
144
        a = T1 + T2;
145
    } while(++j < 64);
146
147
    /* compute intermediate hash value */
148
    ctx->sha_H[0] += a;
149
    ctx->sha_H[1] += b;
150
    ctx->sha_H[2] += c;
151
    ctx->sha_H[3] += d;
152
    ctx->sha_H[4] += e;
153
    ctx->sha_H[5] += f;
154
    ctx->sha_H[6] += g;
155
    ctx->sha_H[7] += h;
156
157
    ctx->sha_blocks++;
158
}
159
160
void sha256_write(sha256_context *ctx, unsigned char *datap, int length)
161
{
162
    while(length > 0) {
163
        if(!ctx->sha_bufCnt) {
164
            while(length >= sizeof(ctx->sha_out)) {
165
                sha256_transform(ctx, datap);
166
                datap += sizeof(ctx->sha_out);
167
                length -= sizeof(ctx->sha_out);
168
            }
169
            if(!length) return;
170
        }
171
        ctx->sha_out[ctx->sha_bufCnt] = *datap++;
172
        length--;
173
        if(++ctx->sha_bufCnt == sizeof(ctx->sha_out)) {
174
            sha256_transform(ctx, &ctx->sha_out[0]);
175
            ctx->sha_bufCnt = 0;
176
        }
177
    }
178
}
179
180
void sha256_final(sha256_context *ctx)
181
{
182
    register int    j;
183
    u_int64_t       bitLength;
184
    u_int32_t       i;
185
    unsigned char   padByte, *datap;
186
187
    bitLength = (ctx->sha_blocks << 9) | (ctx->sha_bufCnt << 3);
188
    padByte = 0x80;
189
    sha256_write(ctx, &padByte, 1);
190
191
    /* pad extra space with zeroes */
192
    padByte = 0;
193
    while(ctx->sha_bufCnt != 56) {
194
        sha256_write(ctx, &padByte, 1);
195
    }
196
197
    /* write bit length, big endian byte order */
198
    ctx->sha_out[56] = bitLength >> 56;
199
    ctx->sha_out[57] = bitLength >> 48;
200
    ctx->sha_out[58] = bitLength >> 40;
201
    ctx->sha_out[59] = bitLength >> 32;
202
    ctx->sha_out[60] = bitLength >> 24;
203
    ctx->sha_out[61] = bitLength >> 16;
204
    ctx->sha_out[62] = bitLength >> 8;
205
    ctx->sha_out[63] = bitLength;
206
    sha256_transform(ctx, &ctx->sha_out[0]);
207
    
208
    /* return results in ctx->sha_out[0...31] */
209
    datap = &ctx->sha_out[0];
210
    j = 0;
211
    do {
212
        i = ctx->sha_H[j];
213
        datap[0] = i >> 24;
214
        datap[1] = i >> 16;
215
        datap[2] = i >> 8;
216
        datap[3] = i;
217
        datap += 4;
218
    } while(++j < 8);
219
220
    /* clear sensitive information */
221
    memset(&ctx->sha_out[32], 0, sizeof(sha256_context) - 32);
222
}
223
224
void sha256_hash_buffer(unsigned char *ib, int ile, unsigned char *ob, int ole)
225
{
226
    sha256_context ctx;
227
228
    if(ole < 1) return;
229
    memset(ob, 0, ole);
230
    if(ole > 32) ole = 32;
231
    sha256_init(&ctx);
232
    sha256_write(&ctx, ib, ile);
233
    sha256_final(&ctx);
234
    memcpy(ob, &ctx.sha_out[0], ole);
235
    memset(&ctx, 0, sizeof(ctx));
236
}
237
238
#endif
239
240
#if defined(SHA512_NEEDED)
241
void sha512_init(sha512_context *ctx)
242
{
243
    memcpy(&ctx->sha_H[0], &sha512_hashInit[0], sizeof(ctx->sha_H));
244
    ctx->sha_blocks = 0;
245
    ctx->sha_blocksMSB = 0;
246
    ctx->sha_bufCnt = 0;
247
}
248
#endif
249
250
#if defined(SHA512_NEEDED) || defined(SHA384_NEEDED)
251
#undef S
252
#undef uSig0
253
#undef uSig1
254
#undef lSig0
255
#undef lSig1
256
#define S(x,y)      (((y) >> (x)) | ((y) << (64 - (x))))
257
#define uSig0(x)    ((S(28,(x))) ^ (S(34,(x))) ^ (S(39,(x))))
258
#define uSig1(x)    ((S(14,(x))) ^ (S(18,(x))) ^ (S(41,(x))))
259
#define lSig0(x)    ((S(1,(x))) ^ (S(8,(x))) ^ (R(7,(x))))
260
#define lSig1(x)    ((S(19,(x))) ^ (S(61,(x))) ^ (R(6,(x))))
261
262
static void sha512_transform(sha512_context *ctx, unsigned char *datap)
263
{
264
    register int    j;
265
    u_int64_t       a, b, c, d, e, f, g, h;
266
    u_int64_t       T1, T2, W[80], Wm2, Wm15;
267
268
    /* read the data, big endian byte order */
269
    j = 0;
270
    do {
271
        W[j] = (((u_int64_t)(datap[0]))<<56) | (((u_int64_t)(datap[1]))<<48) |
272
               (((u_int64_t)(datap[2]))<<40) | (((u_int64_t)(datap[3]))<<32) |
273
               (((u_int64_t)(datap[4]))<<24) | (((u_int64_t)(datap[5]))<<16) |
274
               (((u_int64_t)(datap[6]))<<8 ) | ((u_int64_t)(datap[7]));
275
        datap += 8;
276
    } while(++j < 16);
277
    
278
    /* initialize variables a...h */
279
    a = ctx->sha_H[0];
280
    b = ctx->sha_H[1];
281
    c = ctx->sha_H[2];
282
    d = ctx->sha_H[3];
283
    e = ctx->sha_H[4];
284
    f = ctx->sha_H[5];
285
    g = ctx->sha_H[6];
286
    h = ctx->sha_H[7];
287
288
    /* apply compression function */
289
    j = 0;
290
    do {
291
        if(j >= 16) {
292
            Wm2 = W[j - 2];
293
            Wm15 = W[j - 15];
294
            W[j] = lSig1(Wm2) + W[j - 7] + lSig0(Wm15) + W[j - 16];
295
        }
296
        T1 = h + uSig1(e) + Ch(e,f,g) + sha512_K[j] + W[j];
297
        T2 = uSig0(a) + Maj(a,b,c);
298
        h = g; g = f; f = e;
299
        e = d + T1;
300
        d = c; c = b; b = a;
301
        a = T1 + T2;
302
    } while(++j < 80);
303
304
    /* compute intermediate hash value */
305
    ctx->sha_H[0] += a;
306
    ctx->sha_H[1] += b;
307
    ctx->sha_H[2] += c;
308
    ctx->sha_H[3] += d;
309
    ctx->sha_H[4] += e;
310
    ctx->sha_H[5] += f;
311
    ctx->sha_H[6] += g;
312
    ctx->sha_H[7] += h;
313
314
    ctx->sha_blocks++;
315
    if(!ctx->sha_blocks) ctx->sha_blocksMSB++;
316
}
317
318
void sha512_write(sha512_context *ctx, unsigned char *datap, int length)
319
{
320
    while(length > 0) {
321
        if(!ctx->sha_bufCnt) {
322
            while(length >= sizeof(ctx->sha_out)) {
323
                sha512_transform(ctx, datap);
324
                datap += sizeof(ctx->sha_out);
325
                length -= sizeof(ctx->sha_out);
326
            }
327
            if(!length) return;
328
        }
329
        ctx->sha_out[ctx->sha_bufCnt] = *datap++;
330
        length--;
331
        if(++ctx->sha_bufCnt == sizeof(ctx->sha_out)) {
332
            sha512_transform(ctx, &ctx->sha_out[0]);
333
            ctx->sha_bufCnt = 0;
334
        }
335
    }
336
}
337
338
void sha512_final(sha512_context *ctx)
339
{
340
    register int    j;
341
    u_int64_t       bitLength, bitLengthMSB;
342
    u_int64_t       i;
343
    unsigned char   padByte, *datap;
344
345
    bitLength = (ctx->sha_blocks << 10) | (ctx->sha_bufCnt << 3);
346
    bitLengthMSB = (ctx->sha_blocksMSB << 10) | (ctx->sha_blocks >> 54);
347
    padByte = 0x80;
348
    sha512_write(ctx, &padByte, 1);
349
350
    /* pad extra space with zeroes */
351
    padByte = 0;
352
    while(ctx->sha_bufCnt != 112) {
353
        sha512_write(ctx, &padByte, 1);
354
    }
355
356
    /* write bit length, big endian byte order */
357
    ctx->sha_out[112] = bitLengthMSB >> 56;
358
    ctx->sha_out[113] = bitLengthMSB >> 48;
359
    ctx->sha_out[114] = bitLengthMSB >> 40;
360
    ctx->sha_out[115] = bitLengthMSB >> 32;
361
    ctx->sha_out[116] = bitLengthMSB >> 24;
362
    ctx->sha_out[117] = bitLengthMSB >> 16;
363
    ctx->sha_out[118] = bitLengthMSB >> 8;
364
    ctx->sha_out[119] = bitLengthMSB;
365
    ctx->sha_out[120] = bitLength >> 56;
366
    ctx->sha_out[121] = bitLength >> 48;
367
    ctx->sha_out[122] = bitLength >> 40;
368
    ctx->sha_out[123] = bitLength >> 32;
369
    ctx->sha_out[124] = bitLength >> 24;
370
    ctx->sha_out[125] = bitLength >> 16;
371
    ctx->sha_out[126] = bitLength >> 8;
372
    ctx->sha_out[127] = bitLength;
373
    sha512_transform(ctx, &ctx->sha_out[0]);
374
    
375
    /* return results in ctx->sha_out[0...63] */
376
    datap = &ctx->sha_out[0];
377
    j = 0;
378
    do {
379
        i = ctx->sha_H[j];
380
        datap[0] = i >> 56;
381
        datap[1] = i >> 48;
382
        datap[2] = i >> 40;
383
        datap[3] = i >> 32;
384
        datap[4] = i >> 24;
385
        datap[5] = i >> 16;
386
        datap[6] = i >> 8;
387
        datap[7] = i;
388
        datap += 8;
389
    } while(++j < 8);
390
391
    /* clear sensitive information */
392
    memset(&ctx->sha_out[64], 0, sizeof(sha512_context) - 64);
393
}
394
395
void sha512_hash_buffer(unsigned char *ib, int ile, unsigned char *ob, int ole)
396
{
397
    sha512_context ctx;
398
399
    if(ole < 1) return;
400
    memset(ob, 0, ole);
401
    if(ole > 64) ole = 64;
402
    sha512_init(&ctx);
403
    sha512_write(&ctx, ib, ile);
404
    sha512_final(&ctx);
405
    memcpy(ob, &ctx.sha_out[0], ole);
406
    memset(&ctx, 0, sizeof(ctx));
407
}
408
#endif
409
410
#if defined(SHA384_NEEDED)
411
void sha384_init(sha512_context *ctx)
412
{
413
    memcpy(&ctx->sha_H[0], &sha384_hashInit[0], sizeof(ctx->sha_H));
414
    ctx->sha_blocks = 0;
415
    ctx->sha_blocksMSB = 0;
416
    ctx->sha_bufCnt = 0;
417
}
418
419
void sha384_hash_buffer(unsigned char *ib, int ile, unsigned char *ob, int ole)
420
{
421
    sha512_context ctx;
422
423
    if(ole < 1) return;
424
    memset(ob, 0, ole);
425
    if(ole > 48) ole = 48;
426
    sha384_init(&ctx);
427
    sha512_write(&ctx, ib, ile);
428
    sha512_final(&ctx);
429
    memcpy(ob, &ctx.sha_out[0], ole);
430
    memset(&ctx, 0, sizeof(ctx));
431
}
432
#endif
(-)util-linux-2.12/mount/sha512.h (+45 lines)
Line 0 Link Here
1
/*
2
 *  sha512.h
3
 *
4
 *  Written by Jari Ruusu, April 16 2001
5
 *
6
 *  Copyright 2001 by Jari Ruusu.
7
 *  Redistribution of this file is permitted under the GNU Public License.
8
 */
9
10
#include <sys/types.h>
11
12
typedef struct {
13
    unsigned char   sha_out[64];    /* results are here, bytes 0...31 */
14
    u_int32_t       sha_H[8];
15
    u_int64_t       sha_blocks;
16
    int             sha_bufCnt;
17
} sha256_context;
18
19
typedef struct {
20
    unsigned char   sha_out[128];   /* results are here, bytes 0...63 */
21
    u_int64_t       sha_H[8];
22
    u_int64_t       sha_blocks;
23
    u_int64_t       sha_blocksMSB;
24
    int             sha_bufCnt;
25
} sha512_context;
26
27
/* no sha384_context, use sha512_context */
28
29
/* 256 bit hash, provides 128 bits of security against collision attacks */
30
extern void sha256_init(sha256_context *);
31
extern void sha256_write(sha256_context *, unsigned char *, int);
32
extern void sha256_final(sha256_context *);
33
extern void sha256_hash_buffer(unsigned char *, int, unsigned char *, int);
34
35
/* 512 bit hash, provides 256 bits of security against collision attacks */
36
extern void sha512_init(sha512_context *);
37
extern void sha512_write(sha512_context *, unsigned char *, int);
38
extern void sha512_final(sha512_context *);
39
extern void sha512_hash_buffer(unsigned char *, int, unsigned char *, int);
40
41
/* 384 bit hash, provides 192 bits of security against collision attacks */
42
extern void sha384_init(sha512_context *);
43
/* no sha384_write(), use sha512_write() */
44
/* no sha384_final(), use sha512_final(), result in ctx->sha_out[0...47]  */
45
extern void sha384_hash_buffer(unsigned char *, int, unsigned char *, int);
(-)util-linux-2.12/mount/swapon.8 (+16 lines)
Lines 117-122 Link Here
117
.I /proc/swaps
117
.I /proc/swaps
118
or
118
or
119
.IR /etc/fstab ).
119
.IR /etc/fstab ).
120
.PP
121
If
122
.I loop=/dev/loop?
123
and
124
.I encryption=AES128
125
options are present in
126
.I /etc/fstab
127
then
128
.BR "swapon -a"
129
will set up loop devices using random keys, run
130
.BR "mkswap"
131
on them, and enable encrypted swap on specified loop devices. Encrypted loop
132
devices are set up with page size offset so that unencrypted swap signatures
133
on first page of swap devices are not touched.
134
.BR "swapoff -a"
135
will tear down such loop devices.
120
.SH NOTE
136
.SH NOTE
121
You should not use
137
You should not use
122
.B swapon
138
.B swapon
(-)util-linux-2.12/mount/swapon.c (-10 / +293 lines)
Lines 11-29 Link Here
11
 * 2001-03-22 Erik Troan <ewt@redhat.com>
11
 * 2001-03-22 Erik Troan <ewt@redhat.com>
12
 * - added -e option for -a
12
 * - added -e option for -a
13
 * - -a shouldn't try to add swaps that are already enabled
13
 * - -a shouldn't try to add swaps that are already enabled
14
 * 2002-04-14 Jari Ruusu
15
 * - added encrypted swap support
14
 */
16
 */
15
17
16
#include <ctype.h>
18
#include <ctype.h>
17
#include <stdlib.h>
19
#include <stdlib.h>
18
#include <stdio.h>
20
#include <stdio.h>
21
#include <unistd.h>
19
#include <getopt.h>
22
#include <getopt.h>
20
#include <string.h>
23
#include <string.h>
21
#include <mntent.h>
24
#include <mntent.h>
22
#include <errno.h>
25
#include <errno.h>
26
#include <sys/types.h>
27
#include <sys/wait.h>
23
#include <sys/stat.h>
28
#include <sys/stat.h>
29
#include <fcntl.h>
30
#include <sys/ioctl.h>
31
#include <sys/utsname.h>
32
#include <asm/page.h>
24
#include "swap_constants.h"
33
#include "swap_constants.h"
25
#include "swapargs.h"
34
#include "swapargs.h"
26
#include "nls.h"
35
#include "nls.h"
36
#include "loop.h"
37
#include "xstrncpy.h"
38
#include "sha512.h"
27
39
28
#define streq(s, t)	(strcmp ((s), (t)) == 0)
40
#define streq(s, t)	(strcmp ((s), (t)) == 0)
29
41
Lines 258-263 Link Here
258
}
270
}
259
271
260
static int
272
static int
273
prepare_encrypted_swap(char *partition, char *loop, char *encryption)
274
{
275
	int x, y, fd, ffd;
276
	sha512_context s;
277
	unsigned char b[4096], multiKeyBits[64][32];
278
	char *a[10], *apiName;
279
	struct loop_info64 loopinfo;
280
	FILE *f;
281
282
	/*
283
	 * Some sanity checks
284
	 */
285
	if(strlen(partition) < 1) {
286
		fprintf(stderr, _("swapon: invalid swap device name\n"));
287
		return 0;
288
	}
289
	if(strlen(loop) < 1) {
290
		fprintf(stderr, _("swapon: invalid loop device name\n"));
291
		return 0;
292
	}
293
	if(strlen(encryption) < 1) {
294
		fprintf(stderr, _("swapon: invalid encryption type\n"));
295
		return 0;
296
	}
297
298
	/*
299
	 * Abort if loop device does not exist or is already in use
300
	 */
301
	if((fd = open(loop, O_RDWR)) == -1) {
302
		fprintf(stderr, _("swapon: unable to open loop device %s\n"), loop);
303
		return 0;
304
	}
305
	if(is_unused_loop_device(fd) == 0) {
306
		fprintf(stderr, _("swapon: loop device %s already in use\n"), loop);
307
		goto errout0;
308
	}
309
310
	/*
311
	 * Compute SHA-512 over first 40 KB of old swap data. This data
312
	 * is mostly unknown data encrypted using unknown key. SHA-512 hash
313
	 * output is then used as entropy for new swap encryption key.
314
	 */
315
	if(!(f = fopen(partition, "r+"))) {
316
		fprintf(stderr, _("swapon: unable to open swap device %s\n"), partition);
317
		goto errout0;
318
	}
319
	fseek(f, (long)PAGE_SIZE, SEEK_SET);
320
	sha512_init(&s);
321
	for(x = 0; x < 10; x++) {
322
		if(fread(&b[0], sizeof(b), 1, f) != 1) break;
323
		sha512_write(&s, &b[0], sizeof(b));
324
	}
325
	sha512_final(&s);
326
327
	/*
328
	 * Overwrite 40 KB of old swap data 20 times so that recovering
329
	 * SHA-512 output beyond this point is difficult and expensive.
330
	 */
331
	for(y = 0; y < 20; y++) {
332
		memset(&b[0], y, sizeof(b));
333
		if(fseek(f, (long)PAGE_SIZE, SEEK_SET)) break;
334
		for(x = 0; x < 10; x++) {
335
			if(fwrite(&b[0], sizeof(b), 1, f) != 1) break;
336
		}
337
		if(fflush(f)) break;
338
		if(fsync(fileno(f))) break;
339
	}
340
	fclose(f);
341
342
	/*
343
	 * Use all 512 bits of hash output
344
	 */
345
	memcpy(&b[0], &s.sha_out[0], 64);
346
	memset(&s, 0, sizeof(s));
347
348
	/*
349
	 * Read 32 bytes of random entropy from kernel's random
350
	 * number generator. This code may be executed early on startup
351
	 * scripts and amount of random entropy may be non-existent.
352
	 * SHA-512 of old swap data is used as workaround for missing
353
	 * entropy in kernel's random number generator.
354
	 */
355
	if(!(f = fopen("/dev/urandom", "r"))) {
356
		fprintf(stderr, _("swapon: unable to open /dev/urandom\n"));
357
		goto errout0;
358
	}
359
	fread(&b[64], 32, 1, f);
360
361
	/*
362
	 * Set up struct loop_info64
363
	 */
364
	if((ffd = open(partition, O_RDWR)) < 0) {
365
		fprintf(stderr, _("swapon: unable to open swap device %s\n"), partition);
366
		goto errout1;
367
	}
368
	memset(&loopinfo, 0, sizeof(loopinfo));
369
	xstrncpy(loopinfo.lo_file_name, partition, LO_NAME_SIZE);
370
	loopinfo.lo_encrypt_type = loop_crypt_type(encryption, &loopinfo.lo_encrypt_key_size, &apiName);
371
	if(loopinfo.lo_encrypt_type <= 1) {
372
		fprintf(stderr, _("swapon: unsupported swap encryption type %s\n"), encryption);
373
errout2:
374
		close(ffd);
375
errout1:
376
		fclose(f);
377
errout0:
378
		close(fd);
379
		memset(&loopinfo.lo_encrypt_key[0], 0, sizeof(loopinfo.lo_encrypt_key));
380
		memset(&multiKeyBits[0][0], 0, sizeof(multiKeyBits));
381
		return 0;
382
	}
383
	loopinfo.lo_offset = PAGE_SIZE;
384
	/* single-key hash */
385
	sha512_hash_buffer(&b[0], 64+32, &loopinfo.lo_encrypt_key[0], sizeof(loopinfo.lo_encrypt_key));
386
	/* multi-key hash */
387
	x = 0;
388
	while(x < 64) {
389
		fread(&b[64+32], 16, 1, f);
390
		sha512_hash_buffer(&b[0], 64+32+16, &multiKeyBits[x][0], 32);
391
		x++;
392
	}	
393
394
	/*
395
	 * Try to set up single-key loop
396
	 */
397
	if(ioctl(fd, LOOP_SET_FD, ffd) < 0) {
398
		fprintf(stderr, _("swapon: LOOP_SET_FD failed\n"));
399
		goto errout2;
400
	}
401
	if ((loopinfo.lo_encrypt_type == 18) || (loop_set_status64_ioctl(fd, &loopinfo) < 0)) {
402
		if(try_cryptoapi_loop_interface(fd, &loopinfo, apiName) < 0) {
403
			fprintf(stderr, _("swapon: LOOP_SET_STATUS failed\n"));
404
			ioctl(fd, LOOP_CLR_FD, 0);
405
			goto errout2;
406
		}
407
	}
408
409
	/*
410
	 * Try to put loop to multi-key mode.
411
	 * If this fails, then let it operate in single-key mode.
412
	 */
413
	ioctl(fd, LOOP_MULTI_KEY_SETUP, &multiKeyBits[0][0]);
414
415
	/*
416
	 * Loop is now set up. Clean up the keys.
417
	 */
418
	memset(&loopinfo.lo_encrypt_key[0], 0, sizeof(loopinfo.lo_encrypt_key));
419
	memset(&multiKeyBits[0][0], 0, sizeof(multiKeyBits));
420
	close(ffd);
421
	fclose(f);
422
	close(fd);
423
424
	/*
425
	 * Write 40 KB of zeroes to loop device. That same data is written
426
	 * to underlying partition in encrypted form. This is done to guarantee
427
	 * that next time encrypted swap is initialized, the SHA-512 hash will
428
	 * be different. And, if encrypted swap data writes over this data, that's
429
	 * even better.
430
	 */
431
	if(!(f = fopen(loop, "r+"))) {
432
		fprintf(stderr, _("swapon: unable to open loop device %s\n"), loop);
433
		return 0;
434
	}
435
	memset(&b[0], 0, sizeof(b));
436
	for(x = 0; x < 10; x++) {
437
		if(fwrite(&b[0], sizeof(b), 1, f) != 1) break;
438
	}
439
	fflush(f);
440
	fsync(fileno(f));
441
	fclose(f);
442
	sync();
443
444
	/*
445
	 * Run mkswap on loop device so that kernel understands it as swap.
446
	 * Redirect stderr to /dev/null and ignore exit value.
447
	 */
448
	if(!(x = fork())) {
449
		if((x = open("/dev/null", O_WRONLY)) >= 0) {
450
			dup2(x, 2);
451
			close(x);
452
		}
453
		a[0] = "mkswap";
454
		a[1] = loop;
455
		a[2] = 0;
456
		execvp(a[0], &a[0]);
457
		execv("/sbin/mkswap", &a[0]);
458
		/* error to stdout, stderr is directed to /dev/null */
459
		printf(_("swapon: unable to execute mkswap\n"));
460
		exit(1);
461
	}
462
	if(x == -1) {
463
		fprintf(stderr, _("swapon: fork failed\n"));
464
		return 0;
465
	}
466
	waitpid(x, &y, 0);
467
	sync();
468
469
	return 1;
470
}
471
472
static void
473
shutdown_encrypted_swap(char *loop)
474
{
475
	int fd;
476
	struct stat statbuf;
477
	struct loop_info64 loopinfo;
478
	unsigned char b[32];
479
	FILE *f;
480
481
	if(stat(loop, &statbuf) == 0 && S_ISBLK(statbuf.st_mode)) {
482
		if((fd = open(loop, O_RDWR)) >= 0) {
483
			if(!loop_get_status64_ioctl(fd, &loopinfo)) {
484
				/*
485
				 * Read 32 bytes of random data from kernel's random
486
				 * number generator and write that to loop device.
487
				 * This preserves some of kernel's random entropy
488
				 * to next activation of encrypted swap on this
489
				 * partition.
490
				 */
491
				if((f = fopen("/dev/urandom", "r")) != NULL) {
492
					fread(&b[0], 32, 1, f);
493
					fclose(f);
494
					write(fd, &b[0], 32);
495
					fsync(fd);
496
				}
497
			}
498
			close(fd);
499
		}
500
		sync();
501
		if((fd = open(loop, O_RDONLY)) >= 0) {
502
			if(!loop_get_status64_ioctl(fd, &loopinfo)) {
503
				ioctl(fd, LOOP_CLR_FD, 0);
504
			}
505
			close(fd);
506
		}
507
	}
508
}
509
510
static int
261
main_swapon(int argc, char *argv[]) {
511
main_swapon(int argc, char *argv[]) {
262
	FILE *fp;
512
	FILE *fp;
263
	struct mntent *fstab;
513
	struct mntent *fstab;
Lines 316-332 Link Here
316
		while ((fstab = getmntent(fp)) != NULL) {
566
		while ((fstab = getmntent(fp)) != NULL) {
317
			char *special = fstab->mnt_fsname;
567
			char *special = fstab->mnt_fsname;
318
568
319
			if (streq(fstab->mnt_type, MNTTYPE_SWAP) &&
569
			if (streq(fstab->mnt_type, MNTTYPE_SWAP)) {
320
			    !is_in_proc_swaps(special)
321
			    && (!ifexists || !access(special, R_OK))) {
322
				/* parse mount options; */
570
				/* parse mount options; */
323
				char *opt, *opts = strdup(fstab->mnt_opts);
571
				char *opt, *opts = strdup(fstab->mnt_opts);
324
	   
572
				char *loop = NULL, *encryption = NULL;
325
				for (opt = strtok(opts, ","); opt != NULL;
573
326
				     opt = strtok(NULL, ","))
574
				for (opt = strtok(opts, ","); opt != NULL; opt = strtok(NULL, ",")) {
327
					if (strncmp(opt, "pri=", 4) == 0)
575
					if (strncmp(opt, "pri=", 4) == 0)
328
						priority = atoi(opt+4);
576
						priority = atoi(opt+4);
329
				status |= do_swapon(special, priority);
577
					if (strncmp(opt, "loop=", 5) == 0)
578
						loop = opt + 5;
579
					if (strncmp(opt, "encryption=", 11) == 0)
580
						encryption = opt + 11;
581
				}
582
				if (loop && encryption) {
583
					if(!is_in_proc_swaps(loop) && (!ifexists || !access(special, R_OK))) {
584
						if (!prepare_encrypted_swap(special, loop, encryption)) {
585
							status |= -1;
586
							continue;
587
						}
588
						status |= do_swapon(loop, priority);
589
					}
590
					continue;
591
				}
592
				if (!is_in_proc_swaps(special) && (!ifexists || !access(special, R_OK))) {
593
					status |= do_swapon(special, priority);
594
				}
330
			}
595
			}
331
		}
596
		}
332
	}
597
	}
Lines 403-411 Link Here
403
			exit(2);
668
			exit(2);
404
		}
669
		}
405
		while ((fstab = getmntent(fp)) != NULL) {
670
		while ((fstab = getmntent(fp)) != NULL) {
406
			if (streq(fstab->mnt_type, MNTTYPE_SWAP) &&
671
			if (streq(fstab->mnt_type, MNTTYPE_SWAP)) {
407
			    !is_in_proc_swaps(fstab->mnt_fsname))
672
				/* parse mount options; */
408
				do_swapoff(fstab->mnt_fsname, QUIET);
673
				char *opt, *opts = strdup(fstab->mnt_opts);
674
				char *loop = NULL, *encryption = NULL;
675
676
				for (opt = strtok(opts, ","); opt != NULL; opt = strtok(NULL, ",")) {
677
					if (strncmp(opt, "loop=", 5) == 0)
678
						loop = opt + 5;
679
					if (strncmp(opt, "encryption=", 11) == 0)
680
						encryption = opt + 11;
681
				}
682
				if (loop && encryption) {
683
					if (!is_in_proc_swaps(loop))
684
						do_swapoff(loop, QUIET);
685
					shutdown_encrypted_swap(loop);
686
					continue;
687
				}
688
				if (!is_in_proc_swaps(fstab->mnt_fsname)) {
689
					do_swapoff(fstab->mnt_fsname, QUIET);
690
				}
691
			}
409
		}
692
		}
410
	}
693
	}
411
694

Return to bug 36882