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