corosync  2.3.6
totemcrypto.c
Go to the documentation of this file.
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 
38 #include "config.h"
39 
40 #include <nss.h>
41 #include <pk11pub.h>
42 #include <pkcs11.h>
43 #include <prerror.h>
44 #include <blapit.h>
45 #include <hasht.h>
46 
47 #define LOGSYS_UTILS_ONLY 1
48 #include <corosync/logsys.h>
49 #include <corosync/totem/totem.h>
50 #include "totemcrypto.h"
51 
52 /*
53  * define onwire crypto header
54  */
55 
59  uint8_t __pad0;
60  uint8_t __pad1;
61 } __attribute__((packed));
62 
63 /*
64  * crypto definitions and conversion tables
65  */
66 
67 #define SALT_SIZE 16
68 
69 /*
70  * This are defined in new NSS. For older one, we will define our own
71  */
72 #ifndef AES_256_KEY_LENGTH
73 #define AES_256_KEY_LENGTH 32
74 #endif
75 
76 #ifndef AES_192_KEY_LENGTH
77 #define AES_192_KEY_LENGTH 24
78 #endif
79 
80 #ifndef AES_128_KEY_LENGTH
81 #define AES_128_KEY_LENGTH 16
82 #endif
83 
84 /*
85  * while CRYPTO_CIPHER_TYPE_2_X are not a real cipher at all,
86  * we still allocate a value for them because we use crypto_crypt_t
87  * internally and we don't want overlaps
88  */
89 
96  CRYPTO_CIPHER_TYPE_2_3 = UINT8_MAX - 1,
98 };
99 
100 CK_MECHANISM_TYPE cipher_to_nss[] = {
101  0, /* CRYPTO_CIPHER_TYPE_NONE */
102  CKM_AES_CBC_PAD, /* CRYPTO_CIPHER_TYPE_AES256 */
103  CKM_AES_CBC_PAD, /* CRYPTO_CIPHER_TYPE_AES192 */
104  CKM_AES_CBC_PAD, /* CRYPTO_CIPHER_TYPE_AES128 */
105  CKM_DES3_CBC_PAD /* CRYPTO_CIPHER_TYPE_3DES */
106 };
107 
108 size_t cipher_key_len[] = {
109  0, /* CRYPTO_CIPHER_TYPE_NONE */
110  AES_256_KEY_LENGTH, /* CRYPTO_CIPHER_TYPE_AES256 */
111  AES_192_KEY_LENGTH, /* CRYPTO_CIPHER_TYPE_AES192 */
112  AES_128_KEY_LENGTH, /* CRYPTO_CIPHER_TYPE_AES128 */
113  24 /* CRYPTO_CIPHER_TYPE_3DES - no magic in nss headers */
114 };
115 
116 size_t cypher_block_len[] = {
117  0, /* CRYPTO_CIPHER_TYPE_NONE */
118  AES_BLOCK_SIZE, /* CRYPTO_CIPHER_TYPE_AES256 */
119  AES_BLOCK_SIZE, /* CRYPTO_CIPHER_TYPE_AES192 */
120  AES_BLOCK_SIZE, /* CRYPTO_CIPHER_TYPE_AES128 */
121  0 /* CRYPTO_CIPHER_TYPE_3DES */
122 };
123 
124 /*
125  * hash definitions and conversion tables
126  */
127 
128 /*
129  * while CRYPTO_HASH_TYPE_2_X are not a real hash mechanism at all,
130  * we still allocate a value for them because we use crypto_hash_t
131  * internally and we don't want overlaps
132  */
133 
141  CRYPTO_HASH_TYPE_2_3 = UINT8_MAX - 1,
143 };
144 
145 CK_MECHANISM_TYPE hash_to_nss[] = {
146  0, /* CRYPTO_HASH_TYPE_NONE */
147  CKM_MD5_HMAC, /* CRYPTO_HASH_TYPE_MD5 */
148  CKM_SHA_1_HMAC, /* CRYPTO_HASH_TYPE_SHA1 */
149  CKM_SHA256_HMAC, /* CRYPTO_HASH_TYPE_SHA256 */
150  CKM_SHA384_HMAC, /* CRYPTO_HASH_TYPE_SHA384 */
151  CKM_SHA512_HMAC /* CRYPTO_HASH_TYPE_SHA512 */
152 };
153 
154 size_t hash_len[] = {
155  0, /* CRYPTO_HASH_TYPE_NONE */
156  MD5_LENGTH, /* CRYPTO_HASH_TYPE_MD5 */
157  SHA1_LENGTH, /* CRYPTO_HASH_TYPE_SHA1 */
158  SHA256_LENGTH, /* CRYPTO_HASH_TYPE_SHA256 */
159  SHA384_LENGTH, /* CRYPTO_HASH_TYPE_SHA384 */
160  SHA512_LENGTH /* CRYPTO_HASH_TYPE_SHA512 */
161 };
162 
163 size_t hash_block_len[] = {
164  0, /* CRYPTO_HASH_TYPE_NONE */
165  MD5_BLOCK_LENGTH, /* CRYPTO_HASH_TYPE_MD5 */
166  SHA1_BLOCK_LENGTH, /* CRYPTO_HASH_TYPE_SHA1 */
167  SHA256_BLOCK_LENGTH, /* CRYPTO_HASH_TYPE_SHA256 */
168  SHA384_BLOCK_LENGTH, /* CRYPTO_HASH_TYPE_SHA384 */
169  SHA512_BLOCK_LENGTH /* CRYPTO_HASH_TYPE_SHA512 */
170 };
171 
173  PK11SymKey *nss_sym_key;
174  PK11SymKey *nss_sym_key_sign;
175 
176  unsigned char private_key[1024];
177 
178  unsigned int private_key_len;
179 
181 
183 
184  unsigned int crypto_header_size;
185 
186  void (*log_printf_func) (
187  int level,
188  int subsys,
189  const char *function,
190  const char *file,
191  int line,
192  const char *format,
193  ...)__attribute__((format(printf, 6, 7)));
194 
195  int log_level_security;
199 };
200 
201 #define log_printf(level, format, args...) \
202 do { \
203  instance->log_printf_func ( \
204  level, instance->log_subsys_id, \
205  __FUNCTION__, __FILE__, __LINE__, \
206  (const char *)format, ##args); \
207 } while (0);
208 
209 /*
210  * crypt/decrypt functions
211  */
212 
213 static int string_to_crypto_cipher_type(const char* crypto_cipher_type)
214 {
215  if (strcmp(crypto_cipher_type, "none") == 0) {
217  } else if (strcmp(crypto_cipher_type, "aes256") == 0) {
219  } else if (strcmp(crypto_cipher_type, "aes192") == 0) {
221  } else if (strcmp(crypto_cipher_type, "aes128") == 0) {
223  } else if (strcmp(crypto_cipher_type, "3des") == 0) {
225  }
227 }
228 
229 static int init_nss_crypto(struct crypto_instance *instance)
230 {
231  PK11SlotInfo* crypt_slot = NULL;
232  SECItem crypt_param;
233 
234  if (!cipher_to_nss[instance->crypto_cipher_type]) {
235  return 0;
236  }
237 
238  crypt_param.type = siBuffer;
239  crypt_param.data = instance->private_key;
240  crypt_param.len = cipher_key_len[instance->crypto_cipher_type];
241 
242  crypt_slot = PK11_GetBestSlot(cipher_to_nss[instance->crypto_cipher_type], NULL);
243  if (crypt_slot == NULL) {
244  log_printf(instance->log_level_security, "Unable to find security slot (err %d)",
245  PR_GetError());
246  return -1;
247  }
248 
249  instance->nss_sym_key = PK11_ImportSymKey(crypt_slot,
250  cipher_to_nss[instance->crypto_cipher_type],
251  PK11_OriginUnwrap, CKA_ENCRYPT|CKA_DECRYPT,
252  &crypt_param, NULL);
253  if (instance->nss_sym_key == NULL) {
254  log_printf(instance->log_level_security, "Failure to import key into NSS (err %d)",
255  PR_GetError());
256  return -1;
257  }
258 
259  PK11_FreeSlot(crypt_slot);
260 
261  return 0;
262 }
263 
264 static int encrypt_nss(
265  struct crypto_instance *instance,
266  const unsigned char *buf_in,
267  const size_t buf_in_len,
268  unsigned char *buf_out,
269  size_t *buf_out_len)
270 {
271  PK11Context* crypt_context = NULL;
272  SECItem crypt_param;
273  SECItem *nss_sec_param = NULL;
274  int tmp1_outlen = 0;
275  unsigned int tmp2_outlen = 0;
276  unsigned char *salt = buf_out;
277  unsigned char *data = buf_out + SALT_SIZE;
278  int err = -1;
279 
280  if (!cipher_to_nss[instance->crypto_cipher_type]) {
281  memcpy(buf_out, buf_in, buf_in_len);
282  *buf_out_len = buf_in_len;
283  return 0;
284  }
285 
286  if (PK11_GenerateRandom (salt, SALT_SIZE) != SECSuccess) {
287  log_printf(instance->log_level_security,
288  "Failure to generate a random number %d",
289  PR_GetError());
290  goto out;
291  }
292 
293  crypt_param.type = siBuffer;
294  crypt_param.data = salt;
295  crypt_param.len = SALT_SIZE;
296 
297  nss_sec_param = PK11_ParamFromIV (cipher_to_nss[instance->crypto_cipher_type],
298  &crypt_param);
299  if (nss_sec_param == NULL) {
300  log_printf(instance->log_level_security,
301  "Failure to set up PKCS11 param (err %d)",
302  PR_GetError());
303  goto out;
304  }
305 
306  /*
307  * Create cipher context for encryption
308  */
309  crypt_context = PK11_CreateContextBySymKey (cipher_to_nss[instance->crypto_cipher_type],
310  CKA_ENCRYPT,
311  instance->nss_sym_key,
312  nss_sec_param);
313  if (!crypt_context) {
314  log_printf(instance->log_level_security,
315  "PK11_CreateContext failed (encrypt) crypt_type=%d (err %d)",
316  (int)cipher_to_nss[instance->crypto_cipher_type],
317  PR_GetError());
318  goto out;
319  }
320 
321  if (PK11_CipherOp(crypt_context, data,
322  &tmp1_outlen,
324  (unsigned char *)buf_in, buf_in_len) != SECSuccess) {
325  log_printf(instance->log_level_security,
326  "PK11_CipherOp failed (encrypt) crypt_type=%d (err %d)",
327  (int)cipher_to_nss[instance->crypto_cipher_type],
328  PR_GetError());
329  goto out;
330  }
331 
332  if (PK11_DigestFinal(crypt_context, data + tmp1_outlen,
333  &tmp2_outlen, FRAME_SIZE_MAX - tmp1_outlen) != SECSuccess) {
334  log_printf(instance->log_level_security,
335  "PK11_DigestFinal failed (encrypt) crypt_type=%d (err %d)",
336  (int)cipher_to_nss[instance->crypto_cipher_type],
337  PR_GetError());
338  goto out;
339 
340  }
341 
342  *buf_out_len = tmp1_outlen + tmp2_outlen + SALT_SIZE;
343 
344  err = 0;
345 
346 out:
347  if (crypt_context) {
348  PK11_DestroyContext(crypt_context, PR_TRUE);
349  }
350  if (nss_sec_param) {
351  SECITEM_FreeItem(nss_sec_param, PR_TRUE);
352  }
353  return err;
354 }
355 
356 static int decrypt_nss (
357  struct crypto_instance *instance,
358  unsigned char *buf,
359  int *buf_len)
360 {
361  PK11Context* decrypt_context = NULL;
362  SECItem decrypt_param;
363  int tmp1_outlen = 0;
364  unsigned int tmp2_outlen = 0;
365  unsigned char *salt = buf;
366  unsigned char *data = salt + SALT_SIZE;
367  int datalen = *buf_len - SALT_SIZE;
368  unsigned char outbuf[FRAME_SIZE_MAX];
369  int outbuf_len;
370  int err = -1;
371 
372  if (!cipher_to_nss[instance->crypto_cipher_type]) {
373  return 0;
374  }
375 
376  /* Create cipher context for decryption */
377  decrypt_param.type = siBuffer;
378  decrypt_param.data = salt;
379  decrypt_param.len = SALT_SIZE;
380 
381  decrypt_context = PK11_CreateContextBySymKey(cipher_to_nss[instance->crypto_cipher_type],
382  CKA_DECRYPT,
383  instance->nss_sym_key, &decrypt_param);
384  if (!decrypt_context) {
385  log_printf(instance->log_level_security,
386  "PK11_CreateContext (decrypt) failed (err %d)",
387  PR_GetError());
388  goto out;
389  }
390 
391  if (PK11_CipherOp(decrypt_context, outbuf, &tmp1_outlen,
392  sizeof(outbuf), data, datalen) != SECSuccess) {
393  log_printf(instance->log_level_security,
394  "PK11_CipherOp (decrypt) failed (err %d)",
395  PR_GetError());
396  goto out;
397  }
398 
399  if (PK11_DigestFinal(decrypt_context, outbuf + tmp1_outlen, &tmp2_outlen,
400  sizeof(outbuf) - tmp1_outlen) != SECSuccess) {
401  log_printf(instance->log_level_security,
402  "PK11_DigestFinal (decrypt) failed (err %d)",
403  PR_GetError());
404  goto out;
405  }
406 
407  outbuf_len = tmp1_outlen + tmp2_outlen;
408 
409  memset(buf, 0, *buf_len);
410  memcpy(buf, outbuf, outbuf_len);
411 
412  *buf_len = outbuf_len;
413 
414  err = 0;
415 
416 out:
417  if (decrypt_context) {
418  PK11_DestroyContext(decrypt_context, PR_TRUE);
419  }
420 
421  return err;
422 }
423 
424 
425 /*
426  * hash/hmac/digest functions
427  */
428 
429 static int string_to_crypto_hash_type(const char* crypto_hash_type)
430 {
431  if (strcmp(crypto_hash_type, "none") == 0) {
432  return CRYPTO_HASH_TYPE_NONE;
433  } else if (strcmp(crypto_hash_type, "md5") == 0) {
434  return CRYPTO_HASH_TYPE_MD5;
435  } else if (strcmp(crypto_hash_type, "sha1") == 0) {
436  return CRYPTO_HASH_TYPE_SHA1;
437  } else if (strcmp(crypto_hash_type, "sha256") == 0) {
439  } else if (strcmp(crypto_hash_type, "sha384") == 0) {
441  } else if (strcmp(crypto_hash_type, "sha512") == 0) {
443  }
444 
445  return CRYPTO_HASH_TYPE_SHA1;
446 }
447 
448 static int init_nss_hash(struct crypto_instance *instance)
449 {
450  PK11SlotInfo* hash_slot = NULL;
451  SECItem hash_param;
452 
453  if (!hash_to_nss[instance->crypto_hash_type]) {
454  return 0;
455  }
456 
457  hash_param.type = siBuffer;
458  hash_param.data = instance->private_key;
459  hash_param.len = instance->private_key_len;
460 
461  hash_slot = PK11_GetBestSlot(hash_to_nss[instance->crypto_hash_type], NULL);
462  if (hash_slot == NULL) {
463  log_printf(instance->log_level_security, "Unable to find security slot (err %d)",
464  PR_GetError());
465  return -1;
466  }
467 
468  instance->nss_sym_key_sign = PK11_ImportSymKey(hash_slot,
469  hash_to_nss[instance->crypto_hash_type],
470  PK11_OriginUnwrap, CKA_SIGN,
471  &hash_param, NULL);
472  if (instance->nss_sym_key_sign == NULL) {
473  log_printf(instance->log_level_security, "Failure to import key into NSS (err %d)",
474  PR_GetError());
475  return -1;
476  }
477 
478  PK11_FreeSlot(hash_slot);
479 
480  return 0;
481 }
482 
483 static int calculate_nss_hash(
484  struct crypto_instance *instance,
485  const unsigned char *buf,
486  const size_t buf_len,
487  unsigned char *hash)
488 {
489  PK11Context* hash_context = NULL;
490  SECItem hash_param;
491  unsigned int hash_tmp_outlen = 0;
492  unsigned char hash_block[hash_block_len[instance->crypto_hash_type]];
493  int err = -1;
494 
495  /* Now do the digest */
496  hash_param.type = siBuffer;
497  hash_param.data = 0;
498  hash_param.len = 0;
499 
500  hash_context = PK11_CreateContextBySymKey(hash_to_nss[instance->crypto_hash_type],
501  CKA_SIGN,
502  instance->nss_sym_key_sign,
503  &hash_param);
504 
505  if (!hash_context) {
506  log_printf(instance->log_level_security,
507  "PK11_CreateContext failed (hash) hash_type=%d (err %d)",
508  (int)hash_to_nss[instance->crypto_hash_type],
509  PR_GetError());
510  goto out;
511  }
512 
513  if (PK11_DigestBegin(hash_context) != SECSuccess) {
514  log_printf(instance->log_level_security,
515  "PK11_DigestBegin failed (hash) hash_type=%d (err %d)",
516  (int)hash_to_nss[instance->crypto_hash_type],
517  PR_GetError());
518  goto out;
519  }
520 
521  if (PK11_DigestOp(hash_context,
522  buf,
523  buf_len) != SECSuccess) {
524  log_printf(instance->log_level_security,
525  "PK11_DigestOp failed (hash) hash_type=%d (err %d)",
526  (int)hash_to_nss[instance->crypto_hash_type],
527  PR_GetError());
528  goto out;
529  }
530 
531  if (PK11_DigestFinal(hash_context,
532  hash_block,
533  &hash_tmp_outlen,
534  hash_block_len[instance->crypto_hash_type]) != SECSuccess) {
535  log_printf(instance->log_level_security,
536  "PK11_DigestFinale failed (hash) hash_type=%d (err %d)",
537  (int)hash_to_nss[instance->crypto_hash_type],
538  PR_GetError());
539  goto out;
540  }
541 
542  memcpy(hash, hash_block, hash_len[instance->crypto_hash_type]);
543  err = 0;
544 
545 out:
546  if (hash_context) {
547  PK11_DestroyContext(hash_context, PR_TRUE);
548  }
549 
550  return err;
551 }
552 
553 /*
554  * global/glue nss functions
555  */
556 
557 static int init_nss_db(struct crypto_instance *instance)
558 {
559  if ((!cipher_to_nss[instance->crypto_cipher_type]) &&
560  (!hash_to_nss[instance->crypto_hash_type])) {
561  return 0;
562  }
563 
564  if (NSS_NoDB_Init(".") != SECSuccess) {
565  log_printf(instance->log_level_security, "NSS DB initialization failed (err %d)",
566  PR_GetError());
567  return -1;
568  }
569 
570  return 0;
571 }
572 
573 static int init_nss(struct crypto_instance *instance,
574  const char *crypto_cipher_type,
575  const char *crypto_hash_type)
576 {
577  log_printf(instance->log_level_notice,
578  "Initializing transmit/receive security (NSS) crypto: %s hash: %s",
579  crypto_cipher_type, crypto_hash_type);
580 
581  if (init_nss_db(instance) < 0) {
582  return -1;
583  }
584 
585  if (init_nss_crypto(instance) < 0) {
586  return -1;
587  }
588 
589  if (init_nss_hash(instance) < 0) {
590  return -1;
591  }
592 
593  return 0;
594 }
595 
596 static int encrypt_and_sign_nss_2_3 (
597  struct crypto_instance *instance,
598  const unsigned char *buf_in,
599  const size_t buf_in_len,
600  unsigned char *buf_out,
601  size_t *buf_out_len)
602 {
603  if (encrypt_nss(instance,
604  buf_in, buf_in_len,
605  buf_out + sizeof(struct crypto_config_header), buf_out_len) < 0) {
606  return -1;
607  }
608 
609  *buf_out_len += sizeof(struct crypto_config_header);
610 
611  if (hash_to_nss[instance->crypto_hash_type]) {
612  if (calculate_nss_hash(instance, buf_out, *buf_out_len, buf_out + *buf_out_len) < 0) {
613  return -1;
614  }
615  *buf_out_len += hash_len[instance->crypto_hash_type];
616  }
617 
618  return 0;
619 }
620 
621 static int authenticate_nss_2_3 (
622  struct crypto_instance *instance,
623  unsigned char *buf,
624  int *buf_len)
625 {
626  if (hash_to_nss[instance->crypto_hash_type]) {
627  unsigned char tmp_hash[hash_len[instance->crypto_hash_type]];
628  int datalen = *buf_len - hash_len[instance->crypto_hash_type];
629 
630  if (calculate_nss_hash(instance, buf, datalen, tmp_hash) < 0) {
631  return -1;
632  }
633 
634  if (memcmp(tmp_hash, buf + datalen, hash_len[instance->crypto_hash_type]) != 0) {
635  log_printf(instance->log_level_error, "Digest does not match");
636  return -1;
637  }
638  *buf_len = datalen;
639  }
640 
641  return 0;
642 }
643 
644 static int decrypt_nss_2_3 (
645  struct crypto_instance *instance,
646  unsigned char *buf,
647  int *buf_len)
648 {
649  *buf_len -= sizeof(struct crypto_config_header);
650 
651  if (decrypt_nss(instance, buf + sizeof(struct crypto_config_header), buf_len) < 0) {
652  return -1;
653  }
654 
655  return 0;
656 }
657 
658 /*
659  * exported API
660  */
661 
663  const char *crypto_cipher_type,
664  const char *crypto_hash_type)
665 {
666  int crypto_cipher = string_to_crypto_cipher_type(crypto_cipher_type);
667  int crypto_hash = string_to_crypto_hash_type(crypto_hash_type);
668  size_t hdr_size = 0;
669  int block_size = 0;
670 
671  hdr_size = sizeof(struct crypto_config_header);
672 
673  if (crypto_hash) {
674  hdr_size += hash_len[crypto_hash];
675  }
676 
677  if (crypto_cipher) {
678  hdr_size += SALT_SIZE;
679  if (cypher_block_len[crypto_cipher]) {
680  block_size = cypher_block_len[crypto_cipher];
681  } else {
682  block_size = PK11_GetBlockSize(crypto_cipher, NULL);
683  if (block_size < 0) {
684  /*
685  * failsafe. we can potentially lose up to 63
686  * byte per packet, but better than fragmenting
687  */
688  block_size = 64;
689  }
690  }
691  hdr_size += (block_size * 2);
692  }
693 
694  return hdr_size;
695 }
696 
697 /*
698  * 2.0 packet format:
699  * crypto_cipher_type | crypto_hash_type | __pad0 | __pad1 | hash | salt | data
700  * only data is encrypted, hash only covers salt + data
701  *
702  * 2.2/2.3 packet format
703  * fake_crypto_cipher_type | fake_crypto_hash_type | __pad0 | __pad1 | salt | data | hash
704  * only data is encrypted, hash covers the whole packet
705  *
706  * we need to leave fake_* unencrypted for older versions of corosync to reject the packets,
707  * we need to leave __pad0|1 unencrypted for performance reasons (saves at least 2 memcpy and
708  * and extra buffer but values are hashed and verified.
709  */
710 
712  struct crypto_instance *instance,
713  const unsigned char *buf_in,
714  const size_t buf_in_len,
715  unsigned char *buf_out,
716  size_t *buf_out_len)
717 {
718  struct crypto_config_header *cch = (struct crypto_config_header *)buf_out;
719  int err;
720 
723  cch->__pad0 = 0;
724  cch->__pad1 = 0;
725 
726  err = encrypt_and_sign_nss_2_3(instance,
727  buf_in, buf_in_len,
728  buf_out, buf_out_len);
729 
730  return err;
731 }
732 
734  unsigned char *buf,
735  int *buf_len)
736 {
737  struct crypto_config_header *cch = (struct crypto_config_header *)buf;
738 
740  log_printf(instance->log_level_security,
741  "Incoming packet has different crypto type. Rejecting");
742  return -1;
743  }
744 
746  log_printf(instance->log_level_security,
747  "Incoming packet has different hash type. Rejecting");
748  return -1;
749  }
750 
751  /*
752  * authenticate packet first
753  */
754 
755  if (authenticate_nss_2_3(instance, buf, buf_len) != 0) {
756  return -1;
757  }
758 
759  /*
760  * now we can "trust" the padding bytes/future features
761  */
762 
763  if ((cch->__pad0 != 0) || (cch->__pad1 != 0)) {
764  log_printf(instance->log_level_security,
765  "Incoming packet appears to have features not supported by this version of corosync. Rejecting");
766  return -1;
767  }
768 
769  /*
770  * decrypt
771  */
772 
773  if (decrypt_nss_2_3(instance, buf, buf_len) != 0) {
774  return -1;
775  }
776 
777  /*
778  * invalidate config header and kill it
779  */
780  cch = NULL;
781  memmove(buf, buf + sizeof(struct crypto_config_header), *buf_len);
782 
783  return 0;
784 }
785 
787  const unsigned char *private_key,
788  unsigned int private_key_len,
789  const char *crypto_cipher_type,
790  const char *crypto_hash_type,
791  void (*log_printf_func) (
792  int level,
793  int subsys,
794  const char *function,
795  const char *file,
796  int line,
797  const char *format,
798  ...)__attribute__((format(printf, 6, 7))),
799  int log_level_security,
800  int log_level_notice,
801  int log_level_error,
802  int log_subsys_id)
803 {
804  struct crypto_instance *instance;
805  instance = malloc(sizeof(*instance));
806  if (instance == NULL) {
807  return (NULL);
808  }
809  memset(instance, 0, sizeof(struct crypto_instance));
810 
811  memcpy(instance->private_key, private_key, private_key_len);
812  instance->private_key_len = private_key_len;
813 
814  instance->crypto_cipher_type = string_to_crypto_cipher_type(crypto_cipher_type);
815  instance->crypto_hash_type = string_to_crypto_hash_type(crypto_hash_type);
816 
817  instance->crypto_header_size = crypto_sec_header_size(crypto_cipher_type, crypto_hash_type);
818 
819  instance->log_printf_func = log_printf_func;
822  instance->log_level_error = log_level_error;
823  instance->log_subsys_id = log_subsys_id;
824 
825  if (init_nss(instance, crypto_cipher_type, crypto_hash_type) < 0) {
826  free(instance);
827  return(NULL);
828  }
829 
830  return (instance);
831 }
unsigned char private_key[1024]
Definition: totemcrypto.c:176
unsigned int crypto_header_size
Definition: totemcrypto.c:184
size_t hash_block_len[]
Definition: totemcrypto.c:163
size_t hash_len[]
Definition: totemcrypto.c:154
size_t crypto_sec_header_size(const char *crypto_cipher_type, const char *crypto_hash_type)
Definition: totemcrypto.c:662
#define log_printf(level, format, args...)
Definition: totemcrypto.c:201
PK11SymKey * nss_sym_key_sign
Definition: totemcrypto.c:174
enum crypto_crypt_t crypto_cipher_type
Definition: totemcrypto.c:180
#define SALT_SIZE
Definition: totemcrypto.c:67
#define AES_256_KEY_LENGTH
Definition: totemcrypto.c:73
crypto_crypt_t
Definition: totemcrypto.c:90
struct crypto_instance * crypto_init(const unsigned char *private_key, unsigned int private_key_len, const char *crypto_cipher_type, const char *crypto_hash_type, void(*log_printf_func)(int level, int subsys, const char *function, const char *file, int line, const char *format,...) __attribute__((format(printf, 6, 7))), int log_level_security, int log_level_notice, int log_level_error, int log_subsys_id)
Definition: totemcrypto.c:786
uint8_t crypto_cipher_type
Definition: totemcrypto.c:57
void(*) in log_level_security)
Definition: totemcrypto.c:193
#define AES_192_KEY_LENGTH
Definition: totemcrypto.c:77
int crypto_encrypt_and_sign(struct crypto_instance *instance, const unsigned char *buf_in, const size_t buf_in_len, unsigned char *buf_out, size_t *buf_out_len)
Definition: totemcrypto.c:711
enum crypto_crypt_t __attribute__
PK11SymKey * nss_sym_key
Definition: totemcrypto.c:173
unsigned int private_key_len
Definition: totemcrypto.c:178
int crypto_authenticate_and_decrypt(struct crypto_instance *instance, unsigned char *buf, int *buf_len)
Definition: totemcrypto.c:733
enum crypto_hash_t crypto_hash_type
Definition: totemcrypto.c:182
#define AES_128_KEY_LENGTH
Definition: totemcrypto.c:81
crypto_hash_t
Definition: totemcrypto.c:134
void(* log_printf_func)(int level, int subsys, const char *function, const char *file, int line, const char *format,...) __attribute__((format(printf
Definition: totemcrypto.c:186
CK_MECHANISM_TYPE cipher_to_nss[]
Definition: totemcrypto.c:100
size_t cipher_key_len[]
Definition: totemcrypto.c:108
#define FRAME_SIZE_MAX
Definition: totem.h:50
size_t cypher_block_len[]
Definition: totemcrypto.c:116
CK_MECHANISM_TYPE hash_to_nss[]
Definition: totemcrypto.c:145
uint8_t crypto_hash_type
Definition: totemcrypto.c:58