1 /* Large capacity key type 2 * 3 * Copyright (C) 2013 Red Hat, Inc. All Rights Reserved. 4 * Written by David Howells (dhowells@redhat.com) 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public Licence 8 * as published by the Free Software Foundation; either version 9 * 2 of the Licence, or (at your option) any later version. 10 */ 11 12 #include <linux/init.h> 13 #include <linux/seq_file.h> 14 #include <linux/file.h> 15 #include <linux/shmem_fs.h> 16 #include <linux/err.h> 17 #include <linux/scatterlist.h> 18 #include <keys/user-type.h> 19 #include <keys/big_key-type.h> 20 #include <crypto/rng.h> 21 #include <crypto/skcipher.h> 22 23 /* 24 * Layout of key payload words. 25 */ 26 enum { 27 big_key_data, 28 big_key_path, 29 big_key_path_2nd_part, 30 big_key_len, 31 }; 32 33 /* 34 * Crypto operation with big_key data 35 */ 36 enum big_key_op { 37 BIG_KEY_ENC, 38 BIG_KEY_DEC, 39 }; 40 41 /* 42 * If the data is under this limit, there's no point creating a shm file to 43 * hold it as the permanently resident metadata for the shmem fs will be at 44 * least as large as the data. 45 */ 46 #define BIG_KEY_FILE_THRESHOLD (sizeof(struct inode) + sizeof(struct dentry)) 47 48 /* 49 * Key size for big_key data encryption 50 */ 51 #define ENC_KEY_SIZE 16 52 53 /* 54 * big_key defined keys take an arbitrary string as the description and an 55 * arbitrary blob of data as the payload 56 */ 57 struct key_type key_type_big_key = { 58 .name = "big_key", 59 .preparse = big_key_preparse, 60 .free_preparse = big_key_free_preparse, 61 .instantiate = generic_key_instantiate, 62 .revoke = big_key_revoke, 63 .destroy = big_key_destroy, 64 .describe = big_key_describe, 65 .read = big_key_read, 66 }; 67 68 /* 69 * Crypto names for big_key data encryption 70 */ 71 static const char big_key_rng_name[] = "stdrng"; 72 static const char big_key_alg_name[] = "ecb(aes)"; 73 74 /* 75 * Crypto algorithms for big_key data encryption 76 */ 77 static struct crypto_rng *big_key_rng; 78 static struct crypto_skcipher *big_key_skcipher; 79 80 /* 81 * Generate random key to encrypt big_key data 82 */ 83 static inline int big_key_gen_enckey(u8 *key) 84 { 85 return crypto_rng_get_bytes(big_key_rng, key, ENC_KEY_SIZE); 86 } 87 88 /* 89 * Encrypt/decrypt big_key data 90 */ 91 static int big_key_crypt(enum big_key_op op, u8 *data, size_t datalen, u8 *key) 92 { 93 int ret = -EINVAL; 94 struct scatterlist sgio; 95 SKCIPHER_REQUEST_ON_STACK(req, big_key_skcipher); 96 97 if (crypto_skcipher_setkey(big_key_skcipher, key, ENC_KEY_SIZE)) { 98 ret = -EAGAIN; 99 goto error; 100 } 101 102 skcipher_request_set_tfm(req, big_key_skcipher); 103 skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP, 104 NULL, NULL); 105 106 sg_init_one(&sgio, data, datalen); 107 skcipher_request_set_crypt(req, &sgio, &sgio, datalen, NULL); 108 109 if (op == BIG_KEY_ENC) 110 ret = crypto_skcipher_encrypt(req); 111 else 112 ret = crypto_skcipher_decrypt(req); 113 114 skcipher_request_zero(req); 115 116 error: 117 return ret; 118 } 119 120 /* 121 * Preparse a big key 122 */ 123 int big_key_preparse(struct key_preparsed_payload *prep) 124 { 125 struct path *path = (struct path *)&prep->payload.data[big_key_path]; 126 struct file *file; 127 u8 *enckey; 128 u8 *data = NULL; 129 ssize_t written; 130 size_t datalen = prep->datalen; 131 int ret; 132 133 ret = -EINVAL; 134 if (datalen <= 0 || datalen > 1024 * 1024 || !prep->data) 135 goto error; 136 137 /* Set an arbitrary quota */ 138 prep->quotalen = 16; 139 140 prep->payload.data[big_key_len] = (void *)(unsigned long)datalen; 141 142 if (datalen > BIG_KEY_FILE_THRESHOLD) { 143 /* Create a shmem file to store the data in. This will permit the data 144 * to be swapped out if needed. 145 * 146 * File content is stored encrypted with randomly generated key. 147 */ 148 size_t enclen = ALIGN(datalen, crypto_skcipher_blocksize(big_key_skcipher)); 149 150 /* prepare aligned data to encrypt */ 151 data = kmalloc(enclen, GFP_KERNEL); 152 if (!data) 153 return -ENOMEM; 154 155 memcpy(data, prep->data, datalen); 156 memset(data + datalen, 0x00, enclen - datalen); 157 158 /* generate random key */ 159 enckey = kmalloc(ENC_KEY_SIZE, GFP_KERNEL); 160 if (!enckey) { 161 ret = -ENOMEM; 162 goto error; 163 } 164 165 ret = big_key_gen_enckey(enckey); 166 if (ret) 167 goto err_enckey; 168 169 /* encrypt aligned data */ 170 ret = big_key_crypt(BIG_KEY_ENC, data, enclen, enckey); 171 if (ret) 172 goto err_enckey; 173 174 /* save aligned data to file */ 175 file = shmem_kernel_file_setup("", enclen, 0); 176 if (IS_ERR(file)) { 177 ret = PTR_ERR(file); 178 goto err_enckey; 179 } 180 181 written = kernel_write(file, data, enclen, 0); 182 if (written != enclen) { 183 ret = written; 184 if (written >= 0) 185 ret = -ENOMEM; 186 goto err_fput; 187 } 188 189 /* Pin the mount and dentry to the key so that we can open it again 190 * later 191 */ 192 prep->payload.data[big_key_data] = enckey; 193 *path = file->f_path; 194 path_get(path); 195 fput(file); 196 kfree(data); 197 } else { 198 /* Just store the data in a buffer */ 199 void *data = kmalloc(datalen, GFP_KERNEL); 200 201 if (!data) 202 return -ENOMEM; 203 204 prep->payload.data[big_key_data] = data; 205 memcpy(data, prep->data, prep->datalen); 206 } 207 return 0; 208 209 err_fput: 210 fput(file); 211 err_enckey: 212 kfree(enckey); 213 error: 214 kfree(data); 215 return ret; 216 } 217 218 /* 219 * Clear preparsement. 220 */ 221 void big_key_free_preparse(struct key_preparsed_payload *prep) 222 { 223 if (prep->datalen > BIG_KEY_FILE_THRESHOLD) { 224 struct path *path = (struct path *)&prep->payload.data[big_key_path]; 225 226 path_put(path); 227 } 228 kfree(prep->payload.data[big_key_data]); 229 } 230 231 /* 232 * dispose of the links from a revoked keyring 233 * - called with the key sem write-locked 234 */ 235 void big_key_revoke(struct key *key) 236 { 237 struct path *path = (struct path *)&key->payload.data[big_key_path]; 238 239 /* clear the quota */ 240 key_payload_reserve(key, 0); 241 if (key_is_instantiated(key) && 242 (size_t)key->payload.data[big_key_len] > BIG_KEY_FILE_THRESHOLD) 243 vfs_truncate(path, 0); 244 } 245 246 /* 247 * dispose of the data dangling from the corpse of a big_key key 248 */ 249 void big_key_destroy(struct key *key) 250 { 251 size_t datalen = (size_t)key->payload.data[big_key_len]; 252 253 if (datalen > BIG_KEY_FILE_THRESHOLD) { 254 struct path *path = (struct path *)&key->payload.data[big_key_path]; 255 256 path_put(path); 257 path->mnt = NULL; 258 path->dentry = NULL; 259 } 260 kfree(key->payload.data[big_key_data]); 261 key->payload.data[big_key_data] = NULL; 262 } 263 264 /* 265 * describe the big_key key 266 */ 267 void big_key_describe(const struct key *key, struct seq_file *m) 268 { 269 size_t datalen = (size_t)key->payload.data[big_key_len]; 270 271 seq_puts(m, key->description); 272 273 if (key_is_instantiated(key)) 274 seq_printf(m, ": %zu [%s]", 275 datalen, 276 datalen > BIG_KEY_FILE_THRESHOLD ? "file" : "buff"); 277 } 278 279 /* 280 * read the key data 281 * - the key's semaphore is read-locked 282 */ 283 long big_key_read(const struct key *key, char __user *buffer, size_t buflen) 284 { 285 size_t datalen = (size_t)key->payload.data[big_key_len]; 286 long ret; 287 288 if (!buffer || buflen < datalen) 289 return datalen; 290 291 if (datalen > BIG_KEY_FILE_THRESHOLD) { 292 struct path *path = (struct path *)&key->payload.data[big_key_path]; 293 struct file *file; 294 u8 *data; 295 u8 *enckey = (u8 *)key->payload.data[big_key_data]; 296 size_t enclen = ALIGN(datalen, crypto_skcipher_blocksize(big_key_skcipher)); 297 298 data = kmalloc(enclen, GFP_KERNEL); 299 if (!data) 300 return -ENOMEM; 301 302 file = dentry_open(path, O_RDONLY, current_cred()); 303 if (IS_ERR(file)) { 304 ret = PTR_ERR(file); 305 goto error; 306 } 307 308 /* read file to kernel and decrypt */ 309 ret = kernel_read(file, 0, data, enclen); 310 if (ret >= 0 && ret != enclen) { 311 ret = -EIO; 312 goto err_fput; 313 } 314 315 ret = big_key_crypt(BIG_KEY_DEC, data, enclen, enckey); 316 if (ret) 317 goto err_fput; 318 319 ret = datalen; 320 321 /* copy decrypted data to user */ 322 if (copy_to_user(buffer, data, datalen) != 0) 323 ret = -EFAULT; 324 325 err_fput: 326 fput(file); 327 error: 328 kfree(data); 329 } else { 330 ret = datalen; 331 if (copy_to_user(buffer, key->payload.data[big_key_data], 332 datalen) != 0) 333 ret = -EFAULT; 334 } 335 336 return ret; 337 } 338 339 /* 340 * Register key type 341 */ 342 static int __init big_key_init(void) 343 { 344 return register_key_type(&key_type_big_key); 345 } 346 347 /* 348 * Initialize big_key crypto and RNG algorithms 349 */ 350 static int __init big_key_crypto_init(void) 351 { 352 int ret = -EINVAL; 353 354 /* init RNG */ 355 big_key_rng = crypto_alloc_rng(big_key_rng_name, 0, 0); 356 if (IS_ERR(big_key_rng)) { 357 big_key_rng = NULL; 358 return -EFAULT; 359 } 360 361 /* seed RNG */ 362 ret = crypto_rng_reset(big_key_rng, NULL, crypto_rng_seedsize(big_key_rng)); 363 if (ret) 364 goto error; 365 366 /* init block cipher */ 367 big_key_skcipher = crypto_alloc_skcipher(big_key_alg_name, 368 0, CRYPTO_ALG_ASYNC); 369 if (IS_ERR(big_key_skcipher)) { 370 big_key_skcipher = NULL; 371 ret = -EFAULT; 372 goto error; 373 } 374 375 return 0; 376 377 error: 378 crypto_free_rng(big_key_rng); 379 big_key_rng = NULL; 380 return ret; 381 } 382 383 device_initcall(big_key_init); 384 late_initcall(big_key_crypto_init); 385