corosync  2.3.4
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 
670  hdr_size = sizeof(struct crypto_config_header);
671 
672  if (crypto_hash) {
673  hdr_size += hash_len[crypto_hash];
674  }
675 
676  if (crypto_cipher) {
677  hdr_size += SALT_SIZE;
678  hdr_size += cypher_block_len[crypto_cipher];
679  }
680 
681  return hdr_size;
682 }
683 
684 /*
685  * 2.0 packet format:
686  * crypto_cipher_type | crypto_hash_type | __pad0 | __pad1 | hash | salt | data
687  * only data is encrypted, hash only covers salt + data
688  *
689  * 2.2/2.3 packet format
690  * fake_crypto_cipher_type | fake_crypto_hash_type | __pad0 | __pad1 | salt | data | hash
691  * only data is encrypted, hash covers the whole packet
692  *
693  * we need to leave fake_* unencrypted for older versions of corosync to reject the packets,
694  * we need to leave __pad0|1 unencrypted for performance reasons (saves at least 2 memcpy and
695  * and extra buffer but values are hashed and verified.
696  */
697 
699  struct crypto_instance *instance,
700  const unsigned char *buf_in,
701  const size_t buf_in_len,
702  unsigned char *buf_out,
703  size_t *buf_out_len)
704 {
705  struct crypto_config_header *cch = (struct crypto_config_header *)buf_out;
706  int err;
707 
710  cch->__pad0 = 0;
711  cch->__pad1 = 0;
712 
713  err = encrypt_and_sign_nss_2_3(instance,
714  buf_in, buf_in_len,
715  buf_out, buf_out_len);
716 
717  return err;
718 }
719 
721  unsigned char *buf,
722  int *buf_len)
723 {
724  struct crypto_config_header *cch = (struct crypto_config_header *)buf;
725 
727  log_printf(instance->log_level_security,
728  "Incoming packet has different crypto type. Rejecting");
729  return -1;
730  }
731 
733  log_printf(instance->log_level_security,
734  "Incoming packet has different hash type. Rejecting");
735  return -1;
736  }
737 
738  /*
739  * authenticate packet first
740  */
741 
742  if (authenticate_nss_2_3(instance, buf, buf_len) != 0) {
743  return -1;
744  }
745 
746  /*
747  * now we can "trust" the padding bytes/future features
748  */
749 
750  if ((cch->__pad0 != 0) || (cch->__pad1 != 0)) {
751  log_printf(instance->log_level_security,
752  "Incoming packet appears to have features not supported by this version of corosync. Rejecting");
753  return -1;
754  }
755 
756  /*
757  * decrypt
758  */
759 
760  if (decrypt_nss_2_3(instance, buf, buf_len) != 0) {
761  return -1;
762  }
763 
764  /*
765  * invalidate config header and kill it
766  */
767  cch = NULL;
768  memmove(buf, buf + sizeof(struct crypto_config_header), *buf_len);
769 
770  return 0;
771 }
772 
774  const unsigned char *private_key,
775  unsigned int private_key_len,
776  const char *crypto_cipher_type,
777  const char *crypto_hash_type,
778  void (*log_printf_func) (
779  int level,
780  int subsys,
781  const char *function,
782  const char *file,
783  int line,
784  const char *format,
785  ...)__attribute__((format(printf, 6, 7))),
786  int log_level_security,
787  int log_level_notice,
788  int log_level_error,
789  int log_subsys_id)
790 {
791  struct crypto_instance *instance;
792  instance = malloc(sizeof(*instance));
793  if (instance == NULL) {
794  return (NULL);
795  }
796  memset(instance, 0, sizeof(struct crypto_instance));
797 
798  memcpy(instance->private_key, private_key, private_key_len);
799  instance->private_key_len = private_key_len;
800 
801  instance->crypto_cipher_type = string_to_crypto_cipher_type(crypto_cipher_type);
802  instance->crypto_hash_type = string_to_crypto_hash_type(crypto_hash_type);
803 
804  instance->crypto_header_size = crypto_sec_header_size(crypto_cipher_type, crypto_hash_type);
805 
806  instance->log_printf_func = log_printf_func;
809  instance->log_level_error = log_level_error;
810  instance->log_subsys_id = log_subsys_id;
811 
812  if (init_nss(instance, crypto_cipher_type, crypto_hash_type) < 0) {
813  free(instance);
814  return(NULL);
815  }
816 
817  return (instance);
818 }
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:773
uint8_t crypto_cipher_type
Definition: totemcrypto.c:57
#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:698
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:720
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
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
void(*) in log_level_security)
Definition: totemcrypto.c:193
uint8_t crypto_hash_type
Definition: totemcrypto.c:58
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