totemcrypto.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755
  1. /*
  2. * Copyright (c) 2006-2012 Red Hat, Inc.
  3. *
  4. * All rights reserved.
  5. *
  6. * Author: Steven Dake (sdake@redhat.com)
  7. * Christine Caulfield (ccaulfie@redhat.com)
  8. * Jan Friesse (jfriesse@redhat.com)
  9. * Fabio M. Di Nitto (fdinitto@redhat.com)
  10. *
  11. * This software licensed under BSD license, the text of which follows:
  12. *
  13. * Redistribution and use in source and binary forms, with or without
  14. * modification, are permitted provided that the following conditions are met:
  15. *
  16. * - Redistributions of source code must retain the above copyright notice,
  17. * this list of conditions and the following disclaimer.
  18. * - Redistributions in binary form must reproduce the above copyright notice,
  19. * this list of conditions and the following disclaimer in the documentation
  20. * and/or other materials provided with the distribution.
  21. * - Neither the name of the MontaVista Software, Inc. nor the names of its
  22. * contributors may be used to endorse or promote products derived from this
  23. * software without specific prior written permission.
  24. *
  25. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  26. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  27. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  28. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  29. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  30. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  31. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  32. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  33. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  34. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  35. * THE POSSIBILITY OF SUCH DAMAGE.
  36. */
  37. #include "config.h"
  38. #include <nss.h>
  39. #include <pk11pub.h>
  40. #include <pkcs11.h>
  41. #include <prerror.h>
  42. #include <blapit.h>
  43. #include <hasht.h>
  44. #define LOGSYS_UTILS_ONLY 1
  45. #include <corosync/logsys.h>
  46. #include <corosync/totem/totem.h>
  47. #include "totemcrypto.h"
  48. /*
  49. * define onwire crypto header
  50. */
  51. struct crypto_config_header {
  52. uint8_t crypto_cipher_type;
  53. uint8_t crypto_hash_type;
  54. uint8_t __pad0;
  55. uint8_t __pad1;
  56. } __attribute__((packed));
  57. /*
  58. * crypto definitions and conversion tables
  59. */
  60. #define SALT_SIZE 16
  61. enum crypto_crypt_t {
  62. CRYPTO_CIPHER_TYPE_NONE = 0,
  63. CRYPTO_CIPHER_TYPE_AES256 = 1,
  64. CRYPTO_CIPHER_TYPE_AES192 = 2,
  65. CRYPTO_CIPHER_TYPE_AES128 = 3,
  66. CRYPTO_CIPHER_TYPE_3DES = 4
  67. };
  68. CK_MECHANISM_TYPE cipher_to_nss[] = {
  69. 0, /* CRYPTO_CIPHER_TYPE_NONE */
  70. CKM_AES_CBC_PAD, /* CRYPTO_CIPHER_TYPE_AES256 */
  71. CKM_AES_CBC_PAD, /* CRYPTO_CIPHER_TYPE_AES192 */
  72. CKM_AES_CBC_PAD, /* CRYPTO_CIPHER_TYPE_AES128 */
  73. CKM_DES3_CBC_PAD /* CRYPTO_CIPHER_TYPE_3DES */
  74. };
  75. size_t cipher_key_len[] = {
  76. 0, /* CRYPTO_CIPHER_TYPE_NONE */
  77. AES_256_KEY_LENGTH, /* CRYPTO_CIPHER_TYPE_AES256 */
  78. AES_192_KEY_LENGTH, /* CRYPTO_CIPHER_TYPE_AES192 */
  79. AES_128_KEY_LENGTH, /* CRYPTO_CIPHER_TYPE_AES128 */
  80. 24 /* CRYPTO_CIPHER_TYPE_3DES - no magic in nss headers */
  81. };
  82. size_t cypher_block_len[] = {
  83. 0, /* CRYPTO_CIPHER_TYPE_NONE */
  84. AES_BLOCK_SIZE, /* CRYPTO_CIPHER_TYPE_AES256 */
  85. AES_BLOCK_SIZE, /* CRYPTO_CIPHER_TYPE_AES192 */
  86. AES_BLOCK_SIZE, /* CRYPTO_CIPHER_TYPE_AES128 */
  87. 0 /* CRYPTO_CIPHER_TYPE_3DES */
  88. };
  89. /*
  90. * hash definitions and conversion tables
  91. */
  92. enum crypto_hash_t {
  93. CRYPTO_HASH_TYPE_NONE = 0,
  94. CRYPTO_HASH_TYPE_MD5 = 1,
  95. CRYPTO_HASH_TYPE_SHA1 = 2,
  96. CRYPTO_HASH_TYPE_SHA256 = 3,
  97. CRYPTO_HASH_TYPE_SHA384 = 4,
  98. CRYPTO_HASH_TYPE_SHA512 = 5
  99. };
  100. CK_MECHANISM_TYPE hash_to_nss[] = {
  101. 0, /* CRYPTO_HASH_TYPE_NONE */
  102. CKM_MD5_HMAC, /* CRYPTO_HASH_TYPE_MD5 */
  103. CKM_SHA_1_HMAC, /* CRYPTO_HASH_TYPE_SHA1 */
  104. CKM_SHA256_HMAC, /* CRYPTO_HASH_TYPE_SHA256 */
  105. CKM_SHA384_HMAC, /* CRYPTO_HASH_TYPE_SHA384 */
  106. CKM_SHA512_HMAC /* CRYPTO_HASH_TYPE_SHA512 */
  107. };
  108. size_t hash_len[] = {
  109. 0, /* CRYPTO_HASH_TYPE_NONE */
  110. MD5_LENGTH, /* CRYPTO_HASH_TYPE_MD5 */
  111. SHA1_LENGTH, /* CRYPTO_HASH_TYPE_SHA1 */
  112. SHA256_LENGTH, /* CRYPTO_HASH_TYPE_SHA256 */
  113. SHA384_LENGTH, /* CRYPTO_HASH_TYPE_SHA384 */
  114. SHA512_LENGTH /* CRYPTO_HASH_TYPE_SHA512 */
  115. };
  116. size_t hash_block_len[] = {
  117. 0, /* CRYPTO_HASH_TYPE_NONE */
  118. MD5_BLOCK_LENGTH, /* CRYPTO_HASH_TYPE_MD5 */
  119. SHA1_BLOCK_LENGTH, /* CRYPTO_HASH_TYPE_SHA1 */
  120. SHA256_BLOCK_LENGTH, /* CRYPTO_HASH_TYPE_SHA256 */
  121. SHA384_BLOCK_LENGTH, /* CRYPTO_HASH_TYPE_SHA384 */
  122. SHA512_BLOCK_LENGTH /* CRYPTO_HASH_TYPE_SHA512 */
  123. };
  124. struct crypto_instance {
  125. PK11SymKey *nss_sym_key;
  126. PK11SymKey *nss_sym_key_sign;
  127. unsigned char private_key[1024];
  128. unsigned int private_key_len;
  129. enum crypto_crypt_t crypto_cipher_type;
  130. enum crypto_hash_t crypto_hash_type;
  131. unsigned int crypto_header_size;
  132. void (*log_printf_func) (
  133. int level,
  134. int subsys,
  135. const char *function,
  136. const char *file,
  137. int line,
  138. const char *format,
  139. ...)__attribute__((format(printf, 6, 7)));
  140. int log_level_security;
  141. int log_level_notice;
  142. int log_level_error;
  143. int log_subsys_id;
  144. };
  145. #define log_printf(level, format, args...) \
  146. do { \
  147. instance->log_printf_func ( \
  148. level, instance->log_subsys_id, \
  149. __FUNCTION__, __FILE__, __LINE__, \
  150. (const char *)format, ##args); \
  151. } while (0);
  152. /*
  153. * crypt/decrypt functions
  154. */
  155. static int string_to_crypto_cipher_type(const char* crypto_cipher_type)
  156. {
  157. if (strcmp(crypto_cipher_type, "none") == 0) {
  158. return CRYPTO_CIPHER_TYPE_NONE;
  159. } else if (strcmp(crypto_cipher_type, "aes256") == 0) {
  160. return CRYPTO_CIPHER_TYPE_AES256;
  161. } else if (strcmp(crypto_cipher_type, "aes192") == 0) {
  162. return CRYPTO_CIPHER_TYPE_AES192;
  163. } else if (strcmp(crypto_cipher_type, "aes128") == 0) {
  164. return CRYPTO_CIPHER_TYPE_AES128;
  165. } else if (strcmp(crypto_cipher_type, "3des") == 0) {
  166. return CRYPTO_CIPHER_TYPE_3DES;
  167. }
  168. return CRYPTO_CIPHER_TYPE_AES256;
  169. }
  170. static int init_nss_crypto(struct crypto_instance *instance)
  171. {
  172. PK11SlotInfo* crypt_slot = NULL;
  173. SECItem crypt_param;
  174. if (!cipher_to_nss[instance->crypto_cipher_type]) {
  175. return 0;
  176. }
  177. crypt_param.type = siBuffer;
  178. crypt_param.data = instance->private_key;
  179. crypt_param.len = cipher_key_len[instance->crypto_cipher_type];
  180. crypt_slot = PK11_GetBestSlot(cipher_to_nss[instance->crypto_cipher_type], NULL);
  181. if (crypt_slot == NULL) {
  182. log_printf(instance->log_level_security, "Unable to find security slot (err %d)",
  183. PR_GetError());
  184. return -1;
  185. }
  186. instance->nss_sym_key = PK11_ImportSymKey(crypt_slot,
  187. cipher_to_nss[instance->crypto_cipher_type],
  188. PK11_OriginUnwrap, CKA_ENCRYPT|CKA_DECRYPT,
  189. &crypt_param, NULL);
  190. if (instance->nss_sym_key == NULL) {
  191. log_printf(instance->log_level_security, "Failure to import key into NSS (err %d)",
  192. PR_GetError());
  193. return -1;
  194. }
  195. PK11_FreeSlot(crypt_slot);
  196. return 0;
  197. }
  198. static int encrypt_nss(
  199. struct crypto_instance *instance,
  200. const unsigned char *buf_in,
  201. const size_t buf_in_len,
  202. unsigned char *buf_out,
  203. size_t *buf_out_len)
  204. {
  205. PK11Context* crypt_context = NULL;
  206. SECItem crypt_param;
  207. SECItem *nss_sec_param = NULL;
  208. int tmp1_outlen = 0;
  209. unsigned int tmp2_outlen = 0;
  210. unsigned char *salt = buf_out;
  211. unsigned char *data = buf_out + SALT_SIZE;
  212. int err = -1;
  213. if (!cipher_to_nss[instance->crypto_cipher_type]) {
  214. memcpy(buf_out, buf_in, buf_in_len);
  215. *buf_out_len = buf_in_len;
  216. return 0;
  217. }
  218. if (PK11_GenerateRandom (salt, SALT_SIZE) != SECSuccess) {
  219. log_printf(instance->log_level_security,
  220. "Failure to generate a random number %d",
  221. PR_GetError());
  222. goto out;
  223. }
  224. crypt_param.type = siBuffer;
  225. crypt_param.data = salt;
  226. crypt_param.len = SALT_SIZE;
  227. nss_sec_param = PK11_ParamFromIV (cipher_to_nss[instance->crypto_cipher_type],
  228. &crypt_param);
  229. if (nss_sec_param == NULL) {
  230. log_printf(instance->log_level_security,
  231. "Failure to set up PKCS11 param (err %d)",
  232. PR_GetError());
  233. goto out;
  234. }
  235. /*
  236. * Create cipher context for encryption
  237. */
  238. crypt_context = PK11_CreateContextBySymKey (cipher_to_nss[instance->crypto_cipher_type],
  239. CKA_ENCRYPT,
  240. instance->nss_sym_key,
  241. nss_sec_param);
  242. if (!crypt_context) {
  243. log_printf(instance->log_level_security,
  244. "PK11_CreateContext failed (encrypt) crypt_type=%d (err %d)",
  245. (int)cipher_to_nss[instance->crypto_cipher_type],
  246. PR_GetError());
  247. goto out;
  248. }
  249. if (PK11_CipherOp(crypt_context, data,
  250. &tmp1_outlen,
  251. FRAME_SIZE_MAX - instance->crypto_header_size,
  252. (unsigned char *)buf_in, buf_in_len) != SECSuccess) {
  253. log_printf(instance->log_level_security,
  254. "PK11_CipherOp failed (encrypt) crypt_type=%d (err %d)",
  255. (int)cipher_to_nss[instance->crypto_cipher_type],
  256. PR_GetError());
  257. goto out;
  258. }
  259. if (PK11_DigestFinal(crypt_context, data + tmp1_outlen,
  260. &tmp2_outlen, FRAME_SIZE_MAX - tmp1_outlen) != SECSuccess) {
  261. log_printf(instance->log_level_security,
  262. "PK11_DigestFinal failed (encrypt) crypt_type=%d (err %d)",
  263. (int)cipher_to_nss[instance->crypto_cipher_type],
  264. PR_GetError());
  265. goto out;
  266. }
  267. *buf_out_len = tmp1_outlen + tmp2_outlen + SALT_SIZE;
  268. err = 0;
  269. out:
  270. if (crypt_context) {
  271. PK11_DestroyContext(crypt_context, PR_TRUE);
  272. }
  273. if (nss_sec_param) {
  274. SECITEM_FreeItem(nss_sec_param, PR_TRUE);
  275. }
  276. return err;
  277. }
  278. static int decrypt_nss (
  279. struct crypto_instance *instance,
  280. unsigned char *buf,
  281. int *buf_len)
  282. {
  283. PK11Context* decrypt_context = NULL;
  284. SECItem decrypt_param;
  285. int tmp1_outlen = 0;
  286. unsigned int tmp2_outlen = 0;
  287. unsigned char *salt = buf;
  288. unsigned char *data = salt + SALT_SIZE;
  289. int datalen = *buf_len - SALT_SIZE;
  290. unsigned char outbuf[FRAME_SIZE_MAX];
  291. int outbuf_len;
  292. int err = -1;
  293. if (!cipher_to_nss[instance->crypto_cipher_type]) {
  294. return 0;
  295. }
  296. /* Create cipher context for decryption */
  297. decrypt_param.type = siBuffer;
  298. decrypt_param.data = salt;
  299. decrypt_param.len = SALT_SIZE;
  300. decrypt_context = PK11_CreateContextBySymKey(cipher_to_nss[instance->crypto_cipher_type],
  301. CKA_DECRYPT,
  302. instance->nss_sym_key, &decrypt_param);
  303. if (!decrypt_context) {
  304. log_printf(instance->log_level_security,
  305. "PK11_CreateContext (decrypt) failed (err %d)",
  306. PR_GetError());
  307. goto out;
  308. }
  309. if (PK11_CipherOp(decrypt_context, outbuf, &tmp1_outlen,
  310. sizeof(outbuf), data, datalen) != SECSuccess) {
  311. log_printf(instance->log_level_security,
  312. "PK11_CipherOp (decrypt) failed (err %d)",
  313. PR_GetError());
  314. goto out;
  315. }
  316. if (PK11_DigestFinal(decrypt_context, outbuf + tmp1_outlen, &tmp2_outlen,
  317. sizeof(outbuf) - tmp1_outlen) != SECSuccess) {
  318. log_printf(instance->log_level_security,
  319. "PK11_DigestFinal (decrypt) failed (err %d)",
  320. PR_GetError());
  321. goto out;
  322. }
  323. outbuf_len = tmp1_outlen + tmp2_outlen;
  324. memset(buf, 0, *buf_len);
  325. memcpy(buf, outbuf, outbuf_len);
  326. *buf_len = outbuf_len;
  327. err = 0;
  328. out:
  329. if (decrypt_context) {
  330. PK11_DestroyContext(decrypt_context, PR_TRUE);
  331. }
  332. return err;
  333. }
  334. /*
  335. * hash/hmac/digest functions
  336. */
  337. static int string_to_crypto_hash_type(const char* crypto_hash_type)
  338. {
  339. if (strcmp(crypto_hash_type, "none") == 0) {
  340. return CRYPTO_HASH_TYPE_NONE;
  341. } else if (strcmp(crypto_hash_type, "md5") == 0) {
  342. return CRYPTO_HASH_TYPE_MD5;
  343. } else if (strcmp(crypto_hash_type, "sha1") == 0) {
  344. return CRYPTO_HASH_TYPE_SHA1;
  345. } else if (strcmp(crypto_hash_type, "sha256") == 0) {
  346. return CRYPTO_HASH_TYPE_SHA256;
  347. } else if (strcmp(crypto_hash_type, "sha384") == 0) {
  348. return CRYPTO_HASH_TYPE_SHA384;
  349. } else if (strcmp(crypto_hash_type, "sha512") == 0) {
  350. return CRYPTO_HASH_TYPE_SHA512;
  351. }
  352. return CRYPTO_HASH_TYPE_SHA1;
  353. }
  354. static int init_nss_hash(struct crypto_instance *instance)
  355. {
  356. PK11SlotInfo* hash_slot = NULL;
  357. SECItem hash_param;
  358. if (!hash_to_nss[instance->crypto_hash_type]) {
  359. return 0;
  360. }
  361. hash_param.type = siBuffer;
  362. hash_param.data = 0;
  363. hash_param.len = 0;
  364. hash_slot = PK11_GetBestSlot(hash_to_nss[instance->crypto_hash_type], NULL);
  365. if (hash_slot == NULL) {
  366. log_printf(instance->log_level_security, "Unable to find security slot (err %d)",
  367. PR_GetError());
  368. return -1;
  369. }
  370. instance->nss_sym_key_sign = PK11_ImportSymKey(hash_slot,
  371. hash_to_nss[instance->crypto_hash_type],
  372. PK11_OriginUnwrap, CKA_SIGN,
  373. &hash_param, NULL);
  374. if (instance->nss_sym_key_sign == NULL) {
  375. log_printf(instance->log_level_security, "Failure to import key into NSS (err %d)",
  376. PR_GetError());
  377. return -1;
  378. }
  379. PK11_FreeSlot(hash_slot);
  380. return 0;
  381. }
  382. static int calculate_nss_hash(
  383. struct crypto_instance *instance,
  384. const unsigned char *buf,
  385. const size_t buf_len,
  386. unsigned char *hash)
  387. {
  388. PK11Context* hash_context = NULL;
  389. SECItem hash_param;
  390. unsigned int hash_tmp_outlen = 0;
  391. unsigned char hash_block[hash_block_len[instance->crypto_hash_type]];
  392. int err = -1;
  393. /* Now do the digest */
  394. hash_param.type = siBuffer;
  395. hash_param.data = 0;
  396. hash_param.len = 0;
  397. hash_context = PK11_CreateContextBySymKey(hash_to_nss[instance->crypto_hash_type],
  398. CKA_SIGN,
  399. instance->nss_sym_key_sign,
  400. &hash_param);
  401. if (!hash_context) {
  402. log_printf(instance->log_level_security,
  403. "PK11_CreateContext failed (hash) hash_type=%d (err %d)",
  404. (int)hash_to_nss[instance->crypto_hash_type],
  405. PR_GetError());
  406. goto out;
  407. }
  408. if (PK11_DigestBegin(hash_context) != SECSuccess) {
  409. log_printf(instance->log_level_security,
  410. "PK11_DigestBegin failed (hash) hash_type=%d (err %d)",
  411. (int)hash_to_nss[instance->crypto_hash_type],
  412. PR_GetError());
  413. goto out;
  414. }
  415. if (PK11_DigestOp(hash_context,
  416. buf,
  417. buf_len) != SECSuccess) {
  418. log_printf(instance->log_level_security,
  419. "PK11_DigestOp failed (hash) hash_type=%d (err %d)",
  420. (int)hash_to_nss[instance->crypto_hash_type],
  421. PR_GetError());
  422. goto out;
  423. }
  424. if (PK11_DigestFinal(hash_context,
  425. hash_block,
  426. &hash_tmp_outlen,
  427. hash_block_len[instance->crypto_hash_type]) != SECSuccess) {
  428. log_printf(instance->log_level_security,
  429. "PK11_DigestFinale failed (hash) hash_type=%d (err %d)",
  430. (int)hash_to_nss[instance->crypto_hash_type],
  431. PR_GetError());
  432. goto out;
  433. }
  434. memcpy(hash, hash_block, hash_len[instance->crypto_hash_type]);
  435. err = 0;
  436. out:
  437. if (hash_context) {
  438. PK11_DestroyContext(hash_context, PR_TRUE);
  439. }
  440. return err;
  441. }
  442. /*
  443. * global/glue nss functions
  444. */
  445. static int init_nss_db(struct crypto_instance *instance)
  446. {
  447. if ((!cipher_to_nss[instance->crypto_cipher_type]) &&
  448. (!hash_to_nss[instance->crypto_hash_type])) {
  449. return 0;
  450. }
  451. if (NSS_NoDB_Init(".") != SECSuccess) {
  452. log_printf(instance->log_level_security, "NSS DB initialization failed (err %d)",
  453. PR_GetError());
  454. return -1;
  455. }
  456. return 0;
  457. }
  458. static int init_nss(struct crypto_instance *instance,
  459. const char *crypto_cipher_type,
  460. const char *crypto_hash_type)
  461. {
  462. log_printf(instance->log_level_notice,
  463. "Initializing transmit/receive security (NSS) crypto: %s hash: %s",
  464. crypto_cipher_type, crypto_hash_type);
  465. if (init_nss_db(instance) < 0) {
  466. return -1;
  467. }
  468. if (init_nss_crypto(instance) < 0) {
  469. return -1;
  470. }
  471. if (init_nss_hash(instance) < 0) {
  472. return -1;
  473. }
  474. return 0;
  475. }
  476. static int encrypt_and_sign_nss (
  477. struct crypto_instance *instance,
  478. const unsigned char *buf_in,
  479. const size_t buf_in_len,
  480. unsigned char *buf_out,
  481. size_t *buf_out_len)
  482. {
  483. unsigned char *hash = buf_out;
  484. unsigned char *data = hash + hash_len[instance->crypto_hash_type];
  485. if (encrypt_nss(instance, buf_in, buf_in_len, data, buf_out_len) < 0) {
  486. return -1;
  487. }
  488. if (hash_to_nss[instance->crypto_hash_type]) {
  489. if (calculate_nss_hash(instance, data, *buf_out_len, hash) < 0) {
  490. return -1;
  491. }
  492. *buf_out_len = *buf_out_len + hash_len[instance->crypto_hash_type];
  493. }
  494. return 0;
  495. }
  496. static int authenticate_and_decrypt_nss (
  497. struct crypto_instance *instance,
  498. unsigned char *buf,
  499. int *buf_len)
  500. {
  501. if (hash_to_nss[instance->crypto_hash_type]) {
  502. unsigned char tmp_hash[hash_len[instance->crypto_hash_type]];
  503. unsigned char *hash = buf;
  504. unsigned char *data = hash + hash_len[instance->crypto_hash_type];
  505. int datalen = *buf_len - hash_len[instance->crypto_hash_type];
  506. if (calculate_nss_hash(instance, data, datalen, tmp_hash) < 0) {
  507. return -1;
  508. }
  509. if (memcmp(tmp_hash, hash, hash_len[instance->crypto_hash_type]) != 0) {
  510. log_printf(instance->log_level_error, "Digest does not match");
  511. return -1;
  512. }
  513. memmove(buf, data, datalen);
  514. *buf_len = datalen;
  515. }
  516. if (decrypt_nss(instance, buf, buf_len) < 0) {
  517. return -1;
  518. }
  519. return 0;
  520. }
  521. /*
  522. * exported API
  523. */
  524. size_t crypto_sec_header_size(
  525. const char *crypto_cipher_type,
  526. const char *crypto_hash_type)
  527. {
  528. int crypto_cipher = string_to_crypto_cipher_type(crypto_cipher_type);
  529. int crypto_hash = string_to_crypto_hash_type(crypto_hash_type);
  530. size_t hdr_size = 0;
  531. hdr_size = sizeof(struct crypto_config_header);
  532. if (crypto_hash) {
  533. hdr_size += hash_len[crypto_hash];
  534. }
  535. if (crypto_cipher) {
  536. hdr_size += SALT_SIZE;
  537. hdr_size += cypher_block_len[crypto_cipher];
  538. }
  539. return hdr_size;
  540. }
  541. int crypto_encrypt_and_sign (
  542. struct crypto_instance *instance,
  543. const unsigned char *buf_in,
  544. const size_t buf_in_len,
  545. unsigned char *buf_out,
  546. size_t *buf_out_len)
  547. {
  548. struct crypto_config_header *cch = (struct crypto_config_header *)buf_out;
  549. int err;
  550. cch->crypto_cipher_type = instance->crypto_cipher_type;
  551. cch->crypto_hash_type = instance->crypto_hash_type;
  552. cch->__pad0 = 0;
  553. cch->__pad1 = 0;
  554. buf_out += sizeof(struct crypto_config_header);
  555. err = encrypt_and_sign_nss(instance,
  556. buf_in, buf_in_len,
  557. buf_out, buf_out_len);
  558. *buf_out_len = *buf_out_len + sizeof(struct crypto_config_header);
  559. return err;
  560. }
  561. int crypto_authenticate_and_decrypt (struct crypto_instance *instance,
  562. unsigned char *buf,
  563. int *buf_len)
  564. {
  565. struct crypto_config_header *cch = (struct crypto_config_header *)buf;
  566. /*
  567. * decode crypto config of incoming packets
  568. */
  569. if (cch->crypto_cipher_type != instance->crypto_cipher_type) {
  570. log_printf(instance->log_level_security,
  571. "Incoming packet has different crypto type. Rejecting");
  572. return -1;
  573. }
  574. if (cch->crypto_hash_type != instance->crypto_hash_type) {
  575. log_printf(instance->log_level_security,
  576. "Incoming packet has different hash type. Rejecting");
  577. return -1;
  578. }
  579. if ((cch->__pad0 != 0) || (cch->__pad1 != 0)) {
  580. log_printf(instance->log_level_security,
  581. "Incoming packet appears to have features not supported by this version of corosync. Rejecting");
  582. return -1;
  583. }
  584. /*
  585. * invalidate config header and kill it
  586. */
  587. cch = NULL;
  588. *buf_len -= sizeof(struct crypto_config_header);
  589. memmove(buf, buf + sizeof(struct crypto_config_header), *buf_len);
  590. return authenticate_and_decrypt_nss(instance, buf, buf_len);
  591. }
  592. struct crypto_instance *crypto_init(
  593. const unsigned char *private_key,
  594. unsigned int private_key_len,
  595. const char *crypto_cipher_type,
  596. const char *crypto_hash_type,
  597. void (*log_printf_func) (
  598. int level,
  599. int subsys,
  600. const char *function,
  601. const char *file,
  602. int line,
  603. const char *format,
  604. ...)__attribute__((format(printf, 6, 7))),
  605. int log_level_security,
  606. int log_level_notice,
  607. int log_level_error,
  608. int log_subsys_id)
  609. {
  610. struct crypto_instance *instance;
  611. instance = malloc(sizeof(*instance));
  612. if (instance == NULL) {
  613. return (NULL);
  614. }
  615. memset(instance, 0, sizeof(struct crypto_instance));
  616. memcpy(instance->private_key, private_key, private_key_len);
  617. instance->private_key_len = private_key_len;
  618. instance->crypto_cipher_type = string_to_crypto_cipher_type(crypto_cipher_type);
  619. instance->crypto_hash_type = string_to_crypto_hash_type(crypto_hash_type);
  620. instance->crypto_header_size = crypto_sec_header_size(crypto_cipher_type, crypto_hash_type);
  621. instance->log_printf_func = log_printf_func;
  622. instance->log_level_security = log_level_security;
  623. instance->log_level_notice = log_level_notice;
  624. instance->log_level_error = log_level_error;
  625. instance->log_subsys_id = log_subsys_id;
  626. if (init_nss(instance, crypto_cipher_type, crypto_hash_type) < 0) {
  627. free(instance);
  628. return(NULL);
  629. }
  630. return (instance);
  631. }