crypto.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412
  1. #include "ceph_debug.h"
  2. #include <linux/err.h>
  3. #include <linux/scatterlist.h>
  4. #include <linux/slab.h>
  5. #include <crypto/hash.h>
  6. #include "crypto.h"
  7. #include "decode.h"
  8. int ceph_crypto_key_encode(struct ceph_crypto_key *key, void **p, void *end)
  9. {
  10. if (*p + sizeof(u16) + sizeof(key->created) +
  11. sizeof(u16) + key->len > end)
  12. return -ERANGE;
  13. ceph_encode_16(p, key->type);
  14. ceph_encode_copy(p, &key->created, sizeof(key->created));
  15. ceph_encode_16(p, key->len);
  16. ceph_encode_copy(p, key->key, key->len);
  17. return 0;
  18. }
  19. int ceph_crypto_key_decode(struct ceph_crypto_key *key, void **p, void *end)
  20. {
  21. ceph_decode_need(p, end, 2*sizeof(u16) + sizeof(key->created), bad);
  22. key->type = ceph_decode_16(p);
  23. ceph_decode_copy(p, &key->created, sizeof(key->created));
  24. key->len = ceph_decode_16(p);
  25. ceph_decode_need(p, end, key->len, bad);
  26. key->key = kmalloc(key->len, GFP_NOFS);
  27. if (!key->key)
  28. return -ENOMEM;
  29. ceph_decode_copy(p, key->key, key->len);
  30. return 0;
  31. bad:
  32. dout("failed to decode crypto key\n");
  33. return -EINVAL;
  34. }
  35. int ceph_crypto_key_unarmor(struct ceph_crypto_key *key, const char *inkey)
  36. {
  37. int inlen = strlen(inkey);
  38. int blen = inlen * 3 / 4;
  39. void *buf, *p;
  40. int ret;
  41. dout("crypto_key_unarmor %s\n", inkey);
  42. buf = kmalloc(blen, GFP_NOFS);
  43. if (!buf)
  44. return -ENOMEM;
  45. blen = ceph_unarmor(buf, inkey, inkey+inlen);
  46. if (blen < 0) {
  47. kfree(buf);
  48. return blen;
  49. }
  50. p = buf;
  51. ret = ceph_crypto_key_decode(key, &p, p + blen);
  52. kfree(buf);
  53. if (ret)
  54. return ret;
  55. dout("crypto_key_unarmor key %p type %d len %d\n", key,
  56. key->type, key->len);
  57. return 0;
  58. }
  59. #define AES_KEY_SIZE 16
  60. static struct crypto_blkcipher *ceph_crypto_alloc_cipher(void)
  61. {
  62. return crypto_alloc_blkcipher("cbc(aes)", 0, CRYPTO_ALG_ASYNC);
  63. }
  64. static const u8 *aes_iv = (u8 *)CEPH_AES_IV;
  65. static int ceph_aes_encrypt(const void *key, int key_len,
  66. void *dst, size_t *dst_len,
  67. const void *src, size_t src_len)
  68. {
  69. struct scatterlist sg_in[2], sg_out[1];
  70. struct crypto_blkcipher *tfm = ceph_crypto_alloc_cipher();
  71. struct blkcipher_desc desc = { .tfm = tfm, .flags = 0 };
  72. int ret;
  73. void *iv;
  74. int ivsize;
  75. size_t zero_padding = (0x10 - (src_len & 0x0f));
  76. char pad[16];
  77. if (IS_ERR(tfm))
  78. return PTR_ERR(tfm);
  79. memset(pad, zero_padding, zero_padding);
  80. *dst_len = src_len + zero_padding;
  81. crypto_blkcipher_setkey((void *)tfm, key, key_len);
  82. sg_init_table(sg_in, 2);
  83. sg_set_buf(&sg_in[0], src, src_len);
  84. sg_set_buf(&sg_in[1], pad, zero_padding);
  85. sg_init_table(sg_out, 1);
  86. sg_set_buf(sg_out, dst, *dst_len);
  87. iv = crypto_blkcipher_crt(tfm)->iv;
  88. ivsize = crypto_blkcipher_ivsize(tfm);
  89. memcpy(iv, aes_iv, ivsize);
  90. /*
  91. print_hex_dump(KERN_ERR, "enc key: ", DUMP_PREFIX_NONE, 16, 1,
  92. key, key_len, 1);
  93. print_hex_dump(KERN_ERR, "enc src: ", DUMP_PREFIX_NONE, 16, 1,
  94. src, src_len, 1);
  95. print_hex_dump(KERN_ERR, "enc pad: ", DUMP_PREFIX_NONE, 16, 1,
  96. pad, zero_padding, 1);
  97. */
  98. ret = crypto_blkcipher_encrypt(&desc, sg_out, sg_in,
  99. src_len + zero_padding);
  100. crypto_free_blkcipher(tfm);
  101. if (ret < 0)
  102. pr_err("ceph_aes_crypt failed %d\n", ret);
  103. /*
  104. print_hex_dump(KERN_ERR, "enc out: ", DUMP_PREFIX_NONE, 16, 1,
  105. dst, *dst_len, 1);
  106. */
  107. return 0;
  108. }
  109. static int ceph_aes_encrypt2(const void *key, int key_len, void *dst,
  110. size_t *dst_len,
  111. const void *src1, size_t src1_len,
  112. const void *src2, size_t src2_len)
  113. {
  114. struct scatterlist sg_in[3], sg_out[1];
  115. struct crypto_blkcipher *tfm = ceph_crypto_alloc_cipher();
  116. struct blkcipher_desc desc = { .tfm = tfm, .flags = 0 };
  117. int ret;
  118. void *iv;
  119. int ivsize;
  120. size_t zero_padding = (0x10 - ((src1_len + src2_len) & 0x0f));
  121. char pad[16];
  122. if (IS_ERR(tfm))
  123. return PTR_ERR(tfm);
  124. memset(pad, zero_padding, zero_padding);
  125. *dst_len = src1_len + src2_len + zero_padding;
  126. crypto_blkcipher_setkey((void *)tfm, key, key_len);
  127. sg_init_table(sg_in, 3);
  128. sg_set_buf(&sg_in[0], src1, src1_len);
  129. sg_set_buf(&sg_in[1], src2, src2_len);
  130. sg_set_buf(&sg_in[2], pad, zero_padding);
  131. sg_init_table(sg_out, 1);
  132. sg_set_buf(sg_out, dst, *dst_len);
  133. iv = crypto_blkcipher_crt(tfm)->iv;
  134. ivsize = crypto_blkcipher_ivsize(tfm);
  135. memcpy(iv, aes_iv, ivsize);
  136. /*
  137. print_hex_dump(KERN_ERR, "enc key: ", DUMP_PREFIX_NONE, 16, 1,
  138. key, key_len, 1);
  139. print_hex_dump(KERN_ERR, "enc src1: ", DUMP_PREFIX_NONE, 16, 1,
  140. src1, src1_len, 1);
  141. print_hex_dump(KERN_ERR, "enc src2: ", DUMP_PREFIX_NONE, 16, 1,
  142. src2, src2_len, 1);
  143. print_hex_dump(KERN_ERR, "enc pad: ", DUMP_PREFIX_NONE, 16, 1,
  144. pad, zero_padding, 1);
  145. */
  146. ret = crypto_blkcipher_encrypt(&desc, sg_out, sg_in,
  147. src1_len + src2_len + zero_padding);
  148. crypto_free_blkcipher(tfm);
  149. if (ret < 0)
  150. pr_err("ceph_aes_crypt2 failed %d\n", ret);
  151. /*
  152. print_hex_dump(KERN_ERR, "enc out: ", DUMP_PREFIX_NONE, 16, 1,
  153. dst, *dst_len, 1);
  154. */
  155. return 0;
  156. }
  157. static int ceph_aes_decrypt(const void *key, int key_len,
  158. void *dst, size_t *dst_len,
  159. const void *src, size_t src_len)
  160. {
  161. struct scatterlist sg_in[1], sg_out[2];
  162. struct crypto_blkcipher *tfm = ceph_crypto_alloc_cipher();
  163. struct blkcipher_desc desc = { .tfm = tfm };
  164. char pad[16];
  165. void *iv;
  166. int ivsize;
  167. int ret;
  168. int last_byte;
  169. if (IS_ERR(tfm))
  170. return PTR_ERR(tfm);
  171. crypto_blkcipher_setkey((void *)tfm, key, key_len);
  172. sg_init_table(sg_in, 1);
  173. sg_init_table(sg_out, 2);
  174. sg_set_buf(sg_in, src, src_len);
  175. sg_set_buf(&sg_out[0], dst, *dst_len);
  176. sg_set_buf(&sg_out[1], pad, sizeof(pad));
  177. iv = crypto_blkcipher_crt(tfm)->iv;
  178. ivsize = crypto_blkcipher_ivsize(tfm);
  179. memcpy(iv, aes_iv, ivsize);
  180. /*
  181. print_hex_dump(KERN_ERR, "dec key: ", DUMP_PREFIX_NONE, 16, 1,
  182. key, key_len, 1);
  183. print_hex_dump(KERN_ERR, "dec in: ", DUMP_PREFIX_NONE, 16, 1,
  184. src, src_len, 1);
  185. */
  186. ret = crypto_blkcipher_decrypt(&desc, sg_out, sg_in, src_len);
  187. crypto_free_blkcipher(tfm);
  188. if (ret < 0) {
  189. pr_err("ceph_aes_decrypt failed %d\n", ret);
  190. return ret;
  191. }
  192. if (src_len <= *dst_len)
  193. last_byte = ((char *)dst)[src_len - 1];
  194. else
  195. last_byte = pad[src_len - *dst_len - 1];
  196. if (last_byte <= 16 && src_len >= last_byte) {
  197. *dst_len = src_len - last_byte;
  198. } else {
  199. pr_err("ceph_aes_decrypt got bad padding %d on src len %d\n",
  200. last_byte, (int)src_len);
  201. return -EPERM; /* bad padding */
  202. }
  203. /*
  204. print_hex_dump(KERN_ERR, "dec out: ", DUMP_PREFIX_NONE, 16, 1,
  205. dst, *dst_len, 1);
  206. */
  207. return 0;
  208. }
  209. static int ceph_aes_decrypt2(const void *key, int key_len,
  210. void *dst1, size_t *dst1_len,
  211. void *dst2, size_t *dst2_len,
  212. const void *src, size_t src_len)
  213. {
  214. struct scatterlist sg_in[1], sg_out[3];
  215. struct crypto_blkcipher *tfm = ceph_crypto_alloc_cipher();
  216. struct blkcipher_desc desc = { .tfm = tfm };
  217. char pad[16];
  218. void *iv;
  219. int ivsize;
  220. int ret;
  221. int last_byte;
  222. if (IS_ERR(tfm))
  223. return PTR_ERR(tfm);
  224. sg_init_table(sg_in, 1);
  225. sg_set_buf(sg_in, src, src_len);
  226. sg_init_table(sg_out, 3);
  227. sg_set_buf(&sg_out[0], dst1, *dst1_len);
  228. sg_set_buf(&sg_out[1], dst2, *dst2_len);
  229. sg_set_buf(&sg_out[2], pad, sizeof(pad));
  230. crypto_blkcipher_setkey((void *)tfm, key, key_len);
  231. iv = crypto_blkcipher_crt(tfm)->iv;
  232. ivsize = crypto_blkcipher_ivsize(tfm);
  233. memcpy(iv, aes_iv, ivsize);
  234. /*
  235. print_hex_dump(KERN_ERR, "dec key: ", DUMP_PREFIX_NONE, 16, 1,
  236. key, key_len, 1);
  237. print_hex_dump(KERN_ERR, "dec in: ", DUMP_PREFIX_NONE, 16, 1,
  238. src, src_len, 1);
  239. */
  240. ret = crypto_blkcipher_decrypt(&desc, sg_out, sg_in, src_len);
  241. crypto_free_blkcipher(tfm);
  242. if (ret < 0) {
  243. pr_err("ceph_aes_decrypt failed %d\n", ret);
  244. return ret;
  245. }
  246. if (src_len <= *dst1_len)
  247. last_byte = ((char *)dst1)[src_len - 1];
  248. else if (src_len <= *dst1_len + *dst2_len)
  249. last_byte = ((char *)dst2)[src_len - *dst1_len - 1];
  250. else
  251. last_byte = pad[src_len - *dst1_len - *dst2_len - 1];
  252. if (last_byte <= 16 && src_len >= last_byte) {
  253. src_len -= last_byte;
  254. } else {
  255. pr_err("ceph_aes_decrypt got bad padding %d on src len %d\n",
  256. last_byte, (int)src_len);
  257. return -EPERM; /* bad padding */
  258. }
  259. if (src_len < *dst1_len) {
  260. *dst1_len = src_len;
  261. *dst2_len = 0;
  262. } else {
  263. *dst2_len = src_len - *dst1_len;
  264. }
  265. /*
  266. print_hex_dump(KERN_ERR, "dec out1: ", DUMP_PREFIX_NONE, 16, 1,
  267. dst1, *dst1_len, 1);
  268. print_hex_dump(KERN_ERR, "dec out2: ", DUMP_PREFIX_NONE, 16, 1,
  269. dst2, *dst2_len, 1);
  270. */
  271. return 0;
  272. }
  273. int ceph_decrypt(struct ceph_crypto_key *secret, void *dst, size_t *dst_len,
  274. const void *src, size_t src_len)
  275. {
  276. switch (secret->type) {
  277. case CEPH_CRYPTO_NONE:
  278. if (*dst_len < src_len)
  279. return -ERANGE;
  280. memcpy(dst, src, src_len);
  281. *dst_len = src_len;
  282. return 0;
  283. case CEPH_CRYPTO_AES:
  284. return ceph_aes_decrypt(secret->key, secret->len, dst,
  285. dst_len, src, src_len);
  286. default:
  287. return -EINVAL;
  288. }
  289. }
  290. int ceph_decrypt2(struct ceph_crypto_key *secret,
  291. void *dst1, size_t *dst1_len,
  292. void *dst2, size_t *dst2_len,
  293. const void *src, size_t src_len)
  294. {
  295. size_t t;
  296. switch (secret->type) {
  297. case CEPH_CRYPTO_NONE:
  298. if (*dst1_len + *dst2_len < src_len)
  299. return -ERANGE;
  300. t = min(*dst1_len, src_len);
  301. memcpy(dst1, src, t);
  302. *dst1_len = t;
  303. src += t;
  304. src_len -= t;
  305. if (src_len) {
  306. t = min(*dst2_len, src_len);
  307. memcpy(dst2, src, t);
  308. *dst2_len = t;
  309. }
  310. return 0;
  311. case CEPH_CRYPTO_AES:
  312. return ceph_aes_decrypt2(secret->key, secret->len,
  313. dst1, dst1_len, dst2, dst2_len,
  314. src, src_len);
  315. default:
  316. return -EINVAL;
  317. }
  318. }
  319. int ceph_encrypt(struct ceph_crypto_key *secret, void *dst, size_t *dst_len,
  320. const void *src, size_t src_len)
  321. {
  322. switch (secret->type) {
  323. case CEPH_CRYPTO_NONE:
  324. if (*dst_len < src_len)
  325. return -ERANGE;
  326. memcpy(dst, src, src_len);
  327. *dst_len = src_len;
  328. return 0;
  329. case CEPH_CRYPTO_AES:
  330. return ceph_aes_encrypt(secret->key, secret->len, dst,
  331. dst_len, src, src_len);
  332. default:
  333. return -EINVAL;
  334. }
  335. }
  336. int ceph_encrypt2(struct ceph_crypto_key *secret, void *dst, size_t *dst_len,
  337. const void *src1, size_t src1_len,
  338. const void *src2, size_t src2_len)
  339. {
  340. switch (secret->type) {
  341. case CEPH_CRYPTO_NONE:
  342. if (*dst_len < src1_len + src2_len)
  343. return -ERANGE;
  344. memcpy(dst, src1, src1_len);
  345. memcpy(dst + src1_len, src2, src2_len);
  346. *dst_len = src1_len + src2_len;
  347. return 0;
  348. case CEPH_CRYPTO_AES:
  349. return ceph_aes_encrypt2(secret->key, secret->len, dst, dst_len,
  350. src1, src1_len, src2, src2_len);
  351. default:
  352. return -EINVAL;
  353. }
  354. }