@@ -39,73 +39,62 @@ static void fname_crypt_complete(struct crypto_async_request *req, int res)
39
39
static int fname_encrypt (struct inode * inode ,
40
40
const struct qstr * iname , struct fscrypt_str * oname )
41
41
{
42
- u32 ciphertext_len ;
43
42
struct skcipher_request * req = NULL ;
44
43
DECLARE_FS_COMPLETION_RESULT (ecr );
45
44
struct fscrypt_info * ci = inode -> i_crypt_info ;
46
45
struct crypto_skcipher * tfm = ci -> ci_ctfm ;
47
46
int res = 0 ;
48
47
char iv [FS_CRYPTO_BLOCK_SIZE ];
49
- struct scatterlist src_sg , dst_sg ;
48
+ struct scatterlist sg ;
50
49
int padding = 4 << (ci -> ci_flags & FS_POLICY_FLAGS_PAD_MASK );
51
- char * workbuf , buf [ 32 ], * alloc_buf = NULL ;
52
- unsigned lim ;
50
+ unsigned int lim ;
51
+ unsigned int cryptlen ;
53
52
54
53
lim = inode -> i_sb -> s_cop -> max_namelen (inode );
55
54
if (iname -> len <= 0 || iname -> len > lim )
56
55
return - EIO ;
57
56
58
- ciphertext_len = max (iname -> len , (u32 )FS_CRYPTO_BLOCK_SIZE );
59
- ciphertext_len = round_up (ciphertext_len , padding );
60
- ciphertext_len = min (ciphertext_len , lim );
57
+ /*
58
+ * Copy the filename to the output buffer for encrypting in-place and
59
+ * pad it with the needed number of NUL bytes.
60
+ */
61
+ cryptlen = max_t (unsigned int , iname -> len , FS_CRYPTO_BLOCK_SIZE );
62
+ cryptlen = round_up (cryptlen , padding );
63
+ cryptlen = min (cryptlen , lim );
64
+ memcpy (oname -> name , iname -> name , iname -> len );
65
+ memset (oname -> name + iname -> len , 0 , cryptlen - iname -> len );
61
66
62
- if (ciphertext_len <= sizeof (buf )) {
63
- workbuf = buf ;
64
- } else {
65
- alloc_buf = kmalloc (ciphertext_len , GFP_NOFS );
66
- if (!alloc_buf )
67
- return - ENOMEM ;
68
- workbuf = alloc_buf ;
69
- }
67
+ /* Initialize the IV */
68
+ memset (iv , 0 , FS_CRYPTO_BLOCK_SIZE );
70
69
71
- /* Allocate request */
70
+ /* Set up the encryption request */
72
71
req = skcipher_request_alloc (tfm , GFP_NOFS );
73
72
if (!req ) {
74
73
printk_ratelimited (KERN_ERR
75
- "%s: crypto_request_alloc() failed\n" , __func__ );
76
- kfree (alloc_buf );
74
+ "%s: skcipher_request_alloc() failed\n" , __func__ );
77
75
return - ENOMEM ;
78
76
}
79
77
skcipher_request_set_callback (req ,
80
78
CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP ,
81
79
fname_crypt_complete , & ecr );
80
+ sg_init_one (& sg , oname -> name , cryptlen );
81
+ skcipher_request_set_crypt (req , & sg , & sg , cryptlen , iv );
82
82
83
- /* Copy the input */
84
- memcpy (workbuf , iname -> name , iname -> len );
85
- if (iname -> len < ciphertext_len )
86
- memset (workbuf + iname -> len , 0 , ciphertext_len - iname -> len );
87
-
88
- /* Initialize IV */
89
- memset (iv , 0 , FS_CRYPTO_BLOCK_SIZE );
90
-
91
- /* Create encryption request */
92
- sg_init_one (& src_sg , workbuf , ciphertext_len );
93
- sg_init_one (& dst_sg , oname -> name , ciphertext_len );
94
- skcipher_request_set_crypt (req , & src_sg , & dst_sg , ciphertext_len , iv );
83
+ /* Do the encryption */
95
84
res = crypto_skcipher_encrypt (req );
96
85
if (res == - EINPROGRESS || res == - EBUSY ) {
86
+ /* Request is being completed asynchronously; wait for it */
97
87
wait_for_completion (& ecr .completion );
98
88
res = ecr .res ;
99
89
}
100
- kfree (alloc_buf );
101
90
skcipher_request_free (req );
102
91
if (res < 0 ) {
103
92
printk_ratelimited (KERN_ERR
104
93
"%s: Error (error code %d)\n" , __func__ , res );
105
94
return res ;
106
95
}
107
96
108
- oname -> len = ciphertext_len ;
97
+ oname -> len = cryptlen ;
109
98
return 0 ;
110
99
}
111
100
0 commit comments