diff options
| author | Miloslav Trmač <mitr@redhat.com> | 2010-10-21 19:23:53 +0200 |
|---|---|---|
| committer | Miloslav Trmač <mitr@redhat.com> | 2010-10-21 19:23:53 +0200 |
| commit | c92c0a92db339e284920cabd2b1ca3b2bb073de1 (patch) | |
| tree | 31620b8c002698744187bae5f518e2879973005b /lib | |
| parent | ec3cc7df67c59dee1f47765dcee202045b87bb1c (diff) | |
| download | ncrypto-c92c0a92db339e284920cabd2b1ca3b2bb073de1.tar.gz ncrypto-c92c0a92db339e284920cabd2b1ca3b2bb073de1.tar.xz ncrypto-c92c0a92db339e284920cabd2b1ca3b2bb073de1.zip | |
Add symmetric key generation
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/ncrypto_local.c | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/lib/ncrypto_local.c b/lib/ncrypto_local.c index 8f570b6..f311d63 100644 --- a/lib/ncrypto_local.c +++ b/lib/ncrypto_local.c @@ -86,6 +86,112 @@ ncr_symm_key_create (struct ncr_symm_key **key, CK_KEY_TYPE type, return CKR_OK; } +/* Return non-zero if the key is unusable */ +#define DES_KEY_SIZE 8 +static int +des3_fixup_key (uint8_t value[static 3 * DES_KEY_SIZE]) +{ + static const uint8_t weak_keys[][DES_KEY_SIZE] = + { + "\x01\x01\x01\x01\x01\x01\x01\x01", + "\x1F\x1F\x1F\x1F\x0E\x0E\x0E\x0E", + "\xE0\xE0\xE0\xE0\xF1\xF1\xF1\xF1", + "\xFE\xFE\xFE\xFE\xFE\xFE\xFE\xFE", + "\x01\xFE\x01\xFE\x01\xFE\x01\xFE", + "\xFE\x01\xFE\x01\xFE\x01\xFE\x01", + "\x1F\xE0\x1F\xE0\x0E\xF1\x0E\xF1", + "\xE0\x1F\xE0\x1F\xF1\x0E\xF1\x0E", + "\x01\xE0\x01\xE0\x01\xF1\x01\xF1", + "\xE0\x01\xE0\x01\xF1\x01\xF1\x01", + "\x1F\xFE\x1F\xFE\x0E\xFE\x0E\xFE", + "\xFE\x1F\xFE\x1F\xFE\x0E\xFE\x0E", + "\x01\x1F\x01\x1F\x01\x0E\x01\x0E", + "\x1F\x01\x1F\x01\x0E\x01\x0E\x01", + "\xE0\xFE\xE0\xFE\xF1\xFE\xF1\xFE", + "\xFE\xE0\xFE\xE0\xFE\xF1\xFE\xF1" + }; + + size_t i; + + for (i = 0; i < 3; i++) + { + uint8_t *key; + size_t j; + + key = value + i * 8; + for (j = 0; j < DES_KEY_SIZE; j++) + { + uint8_t v; + + v = key[i]; + v ^= v >> 4; /* v & 0x0F has the same parity as key[i] */ + v ^= v >> 2; /* v & 0x03 has the same parity as key[i] */ + v ^= v >> 1; /* v & 0x01 has the same parity as key[i] */ + key[i] ^= (v & 0x01) ^ 0x01; /* Ensure odd parity */ + } + for (j = 0; j < G_N_ELEMENTS (weak_keys); j++) + { + if (memcmp (key, weak_keys[j], DES_KEY_SIZE) == 0) + return 1; + } + } + return 0; +} +#undef DES_KEY_SIZE + +CK_RV +ncr_symm_key_generate (struct ncr_symm_key **key, CK_MECHANISM_TYPE mech, + size_t value_size) +{ + struct ncr_symm_key *k; + CK_KEY_TYPE type; + CK_RV res; + + g_return_val_if_fail (key != NULL, CKR_ARGUMENTS_BAD); + /* FIXME: PKCS#11 modules should refuse keys with incorrect parity here */ + + switch (mech) + { + case CKM_AES_KEY_GEN: + type = CKK_AES; + g_return_val_if_fail (value_size == 16 || value_size == 24 + || value_size == 32, CKR_TEMPLATE_INCONSISTENT); + break; + + case CKM_DES3_KEY_GEN: + type = CKK_DES3; + g_return_val_if_fail (value_size == 24 || value_size == 0, + CKR_TEMPLATE_INCONSISTENT); + value_size = 24; + break; + + default: + g_return_val_if_reached (CKR_MECHANISM_INVALID); + } + k = malloc (sizeof (*k) + value_size); + if (k == NULL) + return CKR_HOST_MEMORY; + + k->type = type; + k->size = value_size; + regenerate: + res = ncr_get_random_bytes (k->value, value_size); + if (res != CKR_OK) + { + ncr_symm_key_destroy (k); + return res; + } + + if (type == CKK_DES3) + { + if (des3_fixup_key (k->value) != 0) + goto regenerate; + } + + *key = k; + return CKR_OK; +} + CK_RV ncr_symm_key_destroy (struct ncr_symm_key *key) { |
