corosync  2.4.3
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 
212 };
213 
214 #define MAX_WRAPPED_KEY_LEN 128
215 
216 /*
217  * crypt/decrypt functions
218  */
219 
220 static int string_to_crypto_cipher_type(const char* crypto_cipher_type)
221 {
222  if (strcmp(crypto_cipher_type, "none") == 0) {
224  } else if (strcmp(crypto_cipher_type, "aes256") == 0) {
226  } else if (strcmp(crypto_cipher_type, "aes192") == 0) {
228  } else if (strcmp(crypto_cipher_type, "aes128") == 0) {
230  } else if (strcmp(crypto_cipher_type, "3des") == 0) {
232  }
234 }
235 
236 static PK11SymKey *import_symmetric_key(struct crypto_instance *instance, enum sym_key_type key_type)
237 {
238  SECItem key_item;
239  PK11SlotInfo *slot;
240  PK11SymKey *res_key;
241  CK_MECHANISM_TYPE cipher;
242  CK_ATTRIBUTE_TYPE operation;
243  CK_MECHANISM_TYPE wrap_mechanism;
244  int wrap_key_len;
245  PK11SymKey *wrap_key;
246  PK11Context *wrap_key_crypt_context;
247  SECItem tmp_sec_item;
248  SECItem wrapped_key;
249  int wrapped_key_len;
250  unsigned char wrapped_key_data[MAX_WRAPPED_KEY_LEN];
251  int case_processed;
252 
253  memset(&key_item, 0, sizeof(key_item));
254  slot = NULL;
255  wrap_key = NULL;
256  res_key = NULL;
257  wrap_key_crypt_context = NULL;
258 
259  key_item.type = siBuffer;
260  key_item.data = instance->private_key;
261 
262  case_processed = 0;
263  switch (key_type) {
264  case SYM_KEY_TYPE_CRYPT:
265  key_item.len = cipher_key_len[instance->crypto_cipher_type];
266  cipher = cipher_to_nss[instance->crypto_cipher_type];
267  operation = CKA_ENCRYPT|CKA_DECRYPT;
268  case_processed = 1;
269  break;
270  case SYM_KEY_TYPE_HASH:
271  key_item.len = instance->private_key_len;
272  cipher = hash_to_nss[instance->crypto_hash_type];
273  operation = CKA_SIGN;
274  case_processed = 1;
275  break;
276  /*
277  * Default is not defined intentionally. Compiler shows warning when
278  * new key_type is added
279  */
280  }
281 
282  if (!case_processed) {
283  log_printf(instance->log_level_error, "Unknown key_type");
284  goto exit_res_key;
285  }
286 
287  slot = PK11_GetBestSlot(cipher, NULL);
288  if (slot == NULL) {
289  log_printf(instance->log_level_security, "Unable to find security slot (%d): %s",
290  PR_GetError(), PR_ErrorToString(PR_GetError(), PR_LANGUAGE_I_DEFAULT));
291  goto exit_res_key;
292  }
293 
294  /*
295  * Without FIPS it would be possible to just use
296  * res_key = PK11_ImportSymKey(slot, cipher, PK11_OriginUnwrap, operation, &key_item, NULL);
297  * with FIPS NSS Level 2 certification has to be "workarounded" (so it becomes Level 1) by using
298  * following method:
299  * 1. Generate wrap key
300  * 2. Encrypt authkey with wrap key
301  * 3. Unwrap encrypted authkey using wrap key
302  */
303 
304  /*
305  * Generate wrapping key
306  */
307  wrap_mechanism = PK11_GetBestWrapMechanism(slot);
308  wrap_key_len = PK11_GetBestKeyLength(slot, wrap_mechanism);
309  wrap_key = PK11_KeyGen(slot, wrap_mechanism, NULL, wrap_key_len, NULL);
310  if (wrap_key == NULL) {
311  log_printf(instance->log_level_security, "Unable to generate wrapping key (%d): %s",
312  PR_GetError(), PR_ErrorToString(PR_GetError(), PR_LANGUAGE_I_DEFAULT));
313  goto exit_res_key;
314  }
315 
316  /*
317  * Encrypt authkey with wrapping key
318  */
319 
320  /*
321  * Initialization of IV is not needed because PK11_GetBestWrapMechanism should return ECB mode
322  */
323  memset(&tmp_sec_item, 0, sizeof(tmp_sec_item));
324  wrap_key_crypt_context = PK11_CreateContextBySymKey(wrap_mechanism, CKA_ENCRYPT,
325  wrap_key, &tmp_sec_item);
326  if (wrap_key_crypt_context == NULL) {
327  log_printf(instance->log_level_security, "Unable to create encrypt context (%d): %s",
328  PR_GetError(), PR_ErrorToString(PR_GetError(), PR_LANGUAGE_I_DEFAULT));
329  goto exit_res_key;
330  }
331 
332  wrapped_key_len = (int)sizeof(wrapped_key_data);
333 
334  if (PK11_CipherOp(wrap_key_crypt_context, wrapped_key_data, &wrapped_key_len,
335  sizeof(wrapped_key_data), key_item.data, key_item.len) != SECSuccess) {
336  log_printf(instance->log_level_security, "Unable to encrypt authkey (%d): %s",
337  PR_GetError(), PR_ErrorToString(PR_GetError(), PR_LANGUAGE_I_DEFAULT));
338  goto exit_res_key;
339  }
340 
341  if (PK11_Finalize(wrap_key_crypt_context) != SECSuccess) {
342  log_printf(instance->log_level_security, "Unable to finalize encryption of authkey (%d): %s",
343  PR_GetError(), PR_ErrorToString(PR_GetError(), PR_LANGUAGE_I_DEFAULT));
344  goto exit_res_key;
345  }
346 
347  /*
348  * Finally unwrap sym key
349  */
350  memset(&tmp_sec_item, 0, sizeof(tmp_sec_item));
351  wrapped_key.data = wrapped_key_data;
352  wrapped_key.len = wrapped_key_len;
353 
354  res_key = PK11_UnwrapSymKey(wrap_key, wrap_mechanism, &tmp_sec_item, &wrapped_key,
355  cipher, operation, key_item.len);
356  if (res_key == NULL) {
357  log_printf(instance->log_level_security, "Failure to import key into NSS (%d): %s",
358  PR_GetError(), PR_ErrorToString(PR_GetError(), PR_LANGUAGE_I_DEFAULT));
359  goto exit_res_key;
360  }
361 
362 exit_res_key:
363  if (wrap_key_crypt_context != NULL) {
364  PK11_DestroyContext(wrap_key_crypt_context, PR_TRUE);
365  }
366 
367  if (wrap_key != NULL) {
368  PK11_FreeSymKey(wrap_key);
369  }
370 
371  if (slot != NULL) {
372  PK11_FreeSlot(slot);
373  }
374 
375  return (res_key);
376 }
377 
378 static int init_nss_crypto(struct crypto_instance *instance)
379 {
380 
381  if (!cipher_to_nss[instance->crypto_cipher_type]) {
382  return 0;
383  }
384 
385  instance->nss_sym_key = import_symmetric_key(instance, SYM_KEY_TYPE_CRYPT);
386  if (instance->nss_sym_key == NULL) {
387  return -1;
388  }
389 
390  return 0;
391 }
392 
393 static int encrypt_nss(
394  struct crypto_instance *instance,
395  const unsigned char *buf_in,
396  const size_t buf_in_len,
397  unsigned char *buf_out,
398  size_t *buf_out_len)
399 {
400  PK11Context* crypt_context = NULL;
401  SECItem crypt_param;
402  SECItem *nss_sec_param = NULL;
403  int tmp1_outlen = 0;
404  unsigned int tmp2_outlen = 0;
405  unsigned char *salt = buf_out;
406  unsigned char *data = buf_out + SALT_SIZE;
407  int err = -1;
408 
409  if (!cipher_to_nss[instance->crypto_cipher_type]) {
410  memcpy(buf_out, buf_in, buf_in_len);
411  *buf_out_len = buf_in_len;
412  return 0;
413  }
414 
415  if (PK11_GenerateRandom (salt, SALT_SIZE) != SECSuccess) {
416  log_printf(instance->log_level_security,
417  "Failure to generate a random number %d",
418  PR_GetError());
419  goto out;
420  }
421 
422  crypt_param.type = siBuffer;
423  crypt_param.data = salt;
424  crypt_param.len = SALT_SIZE;
425 
426  nss_sec_param = PK11_ParamFromIV (cipher_to_nss[instance->crypto_cipher_type],
427  &crypt_param);
428  if (nss_sec_param == NULL) {
429  log_printf(instance->log_level_security,
430  "Failure to set up PKCS11 param (err %d)",
431  PR_GetError());
432  goto out;
433  }
434 
435  /*
436  * Create cipher context for encryption
437  */
438  crypt_context = PK11_CreateContextBySymKey (cipher_to_nss[instance->crypto_cipher_type],
439  CKA_ENCRYPT,
440  instance->nss_sym_key,
441  nss_sec_param);
442  if (!crypt_context) {
443  log_printf(instance->log_level_security,
444  "PK11_CreateContext failed (encrypt) crypt_type=%d (%d): %s",
445  (int)cipher_to_nss[instance->crypto_cipher_type],
446  PR_GetError(), PR_ErrorToString(PR_GetError(), PR_LANGUAGE_I_DEFAULT));
447  goto out;
448  }
449 
450  if (PK11_CipherOp(crypt_context, data,
451  &tmp1_outlen,
453  (unsigned char *)buf_in, buf_in_len) != SECSuccess) {
454  log_printf(instance->log_level_security,
455  "PK11_CipherOp failed (encrypt) crypt_type=%d (err %d)",
456  (int)cipher_to_nss[instance->crypto_cipher_type],
457  PR_GetError());
458  goto out;
459  }
460 
461  if (PK11_DigestFinal(crypt_context, data + tmp1_outlen,
462  &tmp2_outlen, FRAME_SIZE_MAX - tmp1_outlen) != SECSuccess) {
463  log_printf(instance->log_level_security,
464  "PK11_DigestFinal failed (encrypt) crypt_type=%d (err %d)",
465  (int)cipher_to_nss[instance->crypto_cipher_type],
466  PR_GetError());
467  goto out;
468 
469  }
470 
471  *buf_out_len = tmp1_outlen + tmp2_outlen + SALT_SIZE;
472 
473  err = 0;
474 
475 out:
476  if (crypt_context) {
477  PK11_DestroyContext(crypt_context, PR_TRUE);
478  }
479  if (nss_sec_param) {
480  SECITEM_FreeItem(nss_sec_param, PR_TRUE);
481  }
482  return err;
483 }
484 
485 static int decrypt_nss (
486  struct crypto_instance *instance,
487  unsigned char *buf,
488  int *buf_len)
489 {
490  PK11Context* decrypt_context = NULL;
491  SECItem decrypt_param;
492  int tmp1_outlen = 0;
493  unsigned int tmp2_outlen = 0;
494  unsigned char *salt = buf;
495  unsigned char *data = salt + SALT_SIZE;
496  int datalen = *buf_len - SALT_SIZE;
497  unsigned char outbuf[FRAME_SIZE_MAX];
498  int outbuf_len;
499  int err = -1;
500 
501  if (!cipher_to_nss[instance->crypto_cipher_type]) {
502  return 0;
503  }
504 
505  /* Create cipher context for decryption */
506  decrypt_param.type = siBuffer;
507  decrypt_param.data = salt;
508  decrypt_param.len = SALT_SIZE;
509 
510  decrypt_context = PK11_CreateContextBySymKey(cipher_to_nss[instance->crypto_cipher_type],
511  CKA_DECRYPT,
512  instance->nss_sym_key, &decrypt_param);
513  if (!decrypt_context) {
514  log_printf(instance->log_level_security,
515  "PK11_CreateContext (decrypt) failed (err %d)",
516  PR_GetError());
517  goto out;
518  }
519 
520  if (PK11_CipherOp(decrypt_context, outbuf, &tmp1_outlen,
521  sizeof(outbuf), data, datalen) != SECSuccess) {
522  log_printf(instance->log_level_security,
523  "PK11_CipherOp (decrypt) failed (err %d)",
524  PR_GetError());
525  goto out;
526  }
527 
528  if (PK11_DigestFinal(decrypt_context, outbuf + tmp1_outlen, &tmp2_outlen,
529  sizeof(outbuf) - tmp1_outlen) != SECSuccess) {
530  log_printf(instance->log_level_security,
531  "PK11_DigestFinal (decrypt) failed (err %d)",
532  PR_GetError());
533  goto out;
534  }
535 
536  outbuf_len = tmp1_outlen + tmp2_outlen;
537 
538  memset(buf, 0, *buf_len);
539  memcpy(buf, outbuf, outbuf_len);
540 
541  *buf_len = outbuf_len;
542 
543  err = 0;
544 
545 out:
546  if (decrypt_context) {
547  PK11_DestroyContext(decrypt_context, PR_TRUE);
548  }
549 
550  return err;
551 }
552 
553 
554 /*
555  * hash/hmac/digest functions
556  */
557 
558 static int string_to_crypto_hash_type(const char* crypto_hash_type)
559 {
560  if (strcmp(crypto_hash_type, "none") == 0) {
561  return CRYPTO_HASH_TYPE_NONE;
562  } else if (strcmp(crypto_hash_type, "md5") == 0) {
563  return CRYPTO_HASH_TYPE_MD5;
564  } else if (strcmp(crypto_hash_type, "sha1") == 0) {
565  return CRYPTO_HASH_TYPE_SHA1;
566  } else if (strcmp(crypto_hash_type, "sha256") == 0) {
568  } else if (strcmp(crypto_hash_type, "sha384") == 0) {
570  } else if (strcmp(crypto_hash_type, "sha512") == 0) {
572  }
573 
574  return CRYPTO_HASH_TYPE_SHA1;
575 }
576 
577 static int init_nss_hash(struct crypto_instance *instance)
578 {
579 
580  if (!hash_to_nss[instance->crypto_hash_type]) {
581  return 0;
582  }
583 
584  instance->nss_sym_key_sign = import_symmetric_key(instance, SYM_KEY_TYPE_HASH);
585  if (instance->nss_sym_key_sign == NULL) {
586  return -1;
587  }
588 
589  return 0;
590 }
591 
592 static int calculate_nss_hash(
593  struct crypto_instance *instance,
594  const unsigned char *buf,
595  const size_t buf_len,
596  unsigned char *hash)
597 {
598  PK11Context* hash_context = NULL;
599  SECItem hash_param;
600  unsigned int hash_tmp_outlen = 0;
601  unsigned char hash_block[hash_block_len[instance->crypto_hash_type]];
602  int err = -1;
603 
604  /* Now do the digest */
605  hash_param.type = siBuffer;
606  hash_param.data = 0;
607  hash_param.len = 0;
608 
609  hash_context = PK11_CreateContextBySymKey(hash_to_nss[instance->crypto_hash_type],
610  CKA_SIGN,
611  instance->nss_sym_key_sign,
612  &hash_param);
613 
614  if (!hash_context) {
615  log_printf(instance->log_level_security,
616  "PK11_CreateContext failed (hash) hash_type=%d (err %d)",
617  (int)hash_to_nss[instance->crypto_hash_type],
618  PR_GetError());
619  goto out;
620  }
621 
622  if (PK11_DigestBegin(hash_context) != SECSuccess) {
623  log_printf(instance->log_level_security,
624  "PK11_DigestBegin failed (hash) hash_type=%d (err %d)",
625  (int)hash_to_nss[instance->crypto_hash_type],
626  PR_GetError());
627  goto out;
628  }
629 
630  if (PK11_DigestOp(hash_context,
631  buf,
632  buf_len) != SECSuccess) {
633  log_printf(instance->log_level_security,
634  "PK11_DigestOp failed (hash) hash_type=%d (err %d)",
635  (int)hash_to_nss[instance->crypto_hash_type],
636  PR_GetError());
637  goto out;
638  }
639 
640  if (PK11_DigestFinal(hash_context,
641  hash_block,
642  &hash_tmp_outlen,
643  hash_block_len[instance->crypto_hash_type]) != SECSuccess) {
644  log_printf(instance->log_level_security,
645  "PK11_DigestFinale failed (hash) hash_type=%d (err %d)",
646  (int)hash_to_nss[instance->crypto_hash_type],
647  PR_GetError());
648  goto out;
649  }
650 
651  memcpy(hash, hash_block, hash_len[instance->crypto_hash_type]);
652  err = 0;
653 
654 out:
655  if (hash_context) {
656  PK11_DestroyContext(hash_context, PR_TRUE);
657  }
658 
659  return err;
660 }
661 
662 /*
663  * global/glue nss functions
664  */
665 
666 static int init_nss_db(struct crypto_instance *instance)
667 {
668  if ((!cipher_to_nss[instance->crypto_cipher_type]) &&
669  (!hash_to_nss[instance->crypto_hash_type])) {
670  return 0;
671  }
672 
673  if (NSS_NoDB_Init(".") != SECSuccess) {
674  log_printf(instance->log_level_security, "NSS DB initialization failed (err %d)",
675  PR_GetError());
676  return -1;
677  }
678 
679  return 0;
680 }
681 
682 static int init_nss(struct crypto_instance *instance,
683  const char *crypto_cipher_type,
684  const char *crypto_hash_type)
685 {
686  log_printf(instance->log_level_notice,
687  "Initializing transmit/receive security (NSS) crypto: %s hash: %s",
688  crypto_cipher_type, crypto_hash_type);
689 
690  if (init_nss_db(instance) < 0) {
691  return -1;
692  }
693 
694  if (init_nss_crypto(instance) < 0) {
695  return -1;
696  }
697 
698  if (init_nss_hash(instance) < 0) {
699  return -1;
700  }
701 
702  return 0;
703 }
704 
705 static int encrypt_and_sign_nss_2_3 (
706  struct crypto_instance *instance,
707  const unsigned char *buf_in,
708  const size_t buf_in_len,
709  unsigned char *buf_out,
710  size_t *buf_out_len)
711 {
712  if (encrypt_nss(instance,
713  buf_in, buf_in_len,
714  buf_out + sizeof(struct crypto_config_header), buf_out_len) < 0) {
715  return -1;
716  }
717 
718  *buf_out_len += sizeof(struct crypto_config_header);
719 
720  if (hash_to_nss[instance->crypto_hash_type]) {
721  if (calculate_nss_hash(instance, buf_out, *buf_out_len, buf_out + *buf_out_len) < 0) {
722  return -1;
723  }
724  *buf_out_len += hash_len[instance->crypto_hash_type];
725  }
726 
727  return 0;
728 }
729 
730 static int authenticate_nss_2_3 (
731  struct crypto_instance *instance,
732  unsigned char *buf,
733  int *buf_len)
734 {
735  if (hash_to_nss[instance->crypto_hash_type]) {
736  unsigned char tmp_hash[hash_len[instance->crypto_hash_type]];
737  int datalen = *buf_len - hash_len[instance->crypto_hash_type];
738 
739  if (*buf_len <= hash_len[instance->crypto_hash_type]) {
740  log_printf(instance->log_level_security, "Received message is too short... ignoring");
741  return -1;
742  }
743 
744  if (calculate_nss_hash(instance, buf, datalen, tmp_hash) < 0) {
745  return -1;
746  }
747 
748  if (memcmp(tmp_hash, buf + datalen, hash_len[instance->crypto_hash_type]) != 0) {
749  log_printf(instance->log_level_error, "Digest does not match");
750  return -1;
751  }
752  *buf_len = datalen;
753  }
754 
755  return 0;
756 }
757 
758 static int decrypt_nss_2_3 (
759  struct crypto_instance *instance,
760  unsigned char *buf,
761  int *buf_len)
762 {
763  *buf_len -= sizeof(struct crypto_config_header);
764 
765  if (decrypt_nss(instance, buf + sizeof(struct crypto_config_header), buf_len) < 0) {
766  return -1;
767  }
768 
769  return 0;
770 }
771 
772 /*
773  * exported API
774  */
775 
777  const char *crypto_cipher_type,
778  const char *crypto_hash_type)
779 {
780  int crypto_cipher = string_to_crypto_cipher_type(crypto_cipher_type);
781  int crypto_hash = string_to_crypto_hash_type(crypto_hash_type);
782  size_t hdr_size = 0;
783  int block_size = 0;
784 
785  hdr_size = sizeof(struct crypto_config_header);
786 
787  if (crypto_hash) {
788  hdr_size += hash_len[crypto_hash];
789  }
790 
791  if (crypto_cipher) {
792  hdr_size += SALT_SIZE;
793  if (cypher_block_len[crypto_cipher]) {
794  block_size = cypher_block_len[crypto_cipher];
795  } else {
796  block_size = PK11_GetBlockSize(crypto_cipher, NULL);
797  if (block_size < 0) {
798  /*
799  * failsafe. we can potentially lose up to 63
800  * byte per packet, but better than fragmenting
801  */
802  block_size = 64;
803  }
804  }
805  hdr_size += (block_size * 2);
806  }
807 
808  return hdr_size;
809 }
810 
812  const struct crypto_instance *instance)
813 {
814 
815  return (instance->crypto_header_size);
816 }
817 
818 /*
819  * 2.0 packet format:
820  * crypto_cipher_type | crypto_hash_type | __pad0 | __pad1 | hash | salt | data
821  * only data is encrypted, hash only covers salt + data
822  *
823  * 2.2/2.3 packet format
824  * fake_crypto_cipher_type | fake_crypto_hash_type | __pad0 | __pad1 | salt | data | hash
825  * only data is encrypted, hash covers the whole packet
826  *
827  * we need to leave fake_* unencrypted for older versions of corosync to reject the packets,
828  * we need to leave __pad0|1 unencrypted for performance reasons (saves at least 2 memcpy and
829  * and extra buffer but values are hashed and verified.
830  */
831 
833  struct crypto_instance *instance,
834  const unsigned char *buf_in,
835  const size_t buf_in_len,
836  unsigned char *buf_out,
837  size_t *buf_out_len)
838 {
839  struct crypto_config_header *cch = (struct crypto_config_header *)buf_out;
840  int err;
841 
844  cch->__pad0 = 0;
845  cch->__pad1 = 0;
846 
847  err = encrypt_and_sign_nss_2_3(instance,
848  buf_in, buf_in_len,
849  buf_out, buf_out_len);
850 
851  return err;
852 }
853 
855  unsigned char *buf,
856  int *buf_len)
857 {
858  struct crypto_config_header *cch = (struct crypto_config_header *)buf;
859 
860  if (*buf_len <= sizeof(struct crypto_config_header)) {
861  log_printf(instance->log_level_security, "Received message is too short... ignoring");
862 
863  return (-1);
864  }
865 
867  log_printf(instance->log_level_security,
868  "Incoming packet has different crypto type. Rejecting");
869  return -1;
870  }
871 
873  log_printf(instance->log_level_security,
874  "Incoming packet has different hash type. Rejecting");
875  return -1;
876  }
877 
878  /*
879  * authenticate packet first
880  */
881 
882  if (authenticate_nss_2_3(instance, buf, buf_len) != 0) {
883  return -1;
884  }
885 
886  /*
887  * now we can "trust" the padding bytes/future features
888  */
889 
890  if ((cch->__pad0 != 0) || (cch->__pad1 != 0)) {
891  log_printf(instance->log_level_security,
892  "Incoming packet appears to have features not supported by this version of corosync. Rejecting");
893  return -1;
894  }
895 
896  /*
897  * decrypt
898  */
899  if (decrypt_nss_2_3(instance, buf, buf_len) != 0) {
900  return -1;
901  }
902 
903  /*
904  * invalidate config header and kill it
905  */
906  cch = NULL;
907  memmove(buf, buf + sizeof(struct crypto_config_header), *buf_len);
908 
909  return 0;
910 }
911 
913  const unsigned char *private_key,
914  unsigned int private_key_len,
915  const char *crypto_cipher_type,
916  const char *crypto_hash_type,
917  void (*log_printf_func) (
918  int level,
919  int subsys,
920  const char *function,
921  const char *file,
922  int line,
923  const char *format,
924  ...)__attribute__((format(printf, 6, 7))),
925  int log_level_security,
926  int log_level_notice,
927  int log_level_error,
928  int log_subsys_id)
929 {
930  struct crypto_instance *instance;
931  instance = malloc(sizeof(*instance));
932  if (instance == NULL) {
933  return (NULL);
934  }
935  memset(instance, 0, sizeof(struct crypto_instance));
936 
937  memcpy(instance->private_key, private_key, private_key_len);
938  instance->private_key_len = private_key_len;
939 
940  instance->crypto_cipher_type = string_to_crypto_cipher_type(crypto_cipher_type);
941  instance->crypto_hash_type = string_to_crypto_hash_type(crypto_hash_type);
942 
943  instance->crypto_header_size = crypto_sec_header_size(crypto_cipher_type, crypto_hash_type);
944 
945  instance->log_printf_func = log_printf_func;
948  instance->log_level_error = log_level_error;
949  instance->log_subsys_id = log_subsys_id;
950 
951  if (init_nss(instance, crypto_cipher_type, crypto_hash_type) < 0) {
952  free(instance);
953  return(NULL);
954  }
955 
956  return (instance);
957 }
unsigned char private_key[1024]
Definition: totemcrypto.c:176
sym_key_type
Definition: totemcrypto.c:209
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:776
size_t crypto_get_current_sec_header_size(const struct crypto_instance *instance)
Definition: totemcrypto.c:811
#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
uint32_t operation
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:912
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:832
#define MAX_WRAPPED_KEY_LEN
Definition: totemcrypto.c:214
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:854
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