| OLD | NEW |
| 1 /* This Source Code Form is subject to the terms of the Mozilla Public | 1 /* This Source Code Form is subject to the terms of the Mozilla Public |
| 2 * License, v. 2.0. If a copy of the MPL was not distributed with this | 2 * License, v. 2.0. If a copy of the MPL was not distributed with this |
| 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
| 4 /* | 4 /* |
| 5 * This file implements PKCS 11 on top of our existing security modules | 5 * This file implements PKCS 11 on top of our existing security modules |
| 6 * | 6 * |
| 7 * For more information about PKCS 11 See PKCS 11 Token Inteface Standard. | 7 * For more information about PKCS 11 See PKCS 11 Token Inteface Standard. |
| 8 * This implementation has two slots: | 8 * This implementation has two slots: |
| 9 * slot 1 is our generic crypto support. It does not require login. | 9 * slot 1 is our generic crypto support. It does not require login. |
| 10 * It supports Public Key ops, and all they bulk ciphers and hashes. | 10 * It supports Public Key ops, and all they bulk ciphers and hashes. |
| (...skipping 5764 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5775 return 16; | 5775 return 16; |
| 5776 case CKK_DES3: | 5776 case CKK_DES3: |
| 5777 return 24; | 5777 return 24; |
| 5778 /* IDEA and CAST need to be added */ | 5778 /* IDEA and CAST need to be added */ |
| 5779 default: | 5779 default: |
| 5780 break; | 5780 break; |
| 5781 } | 5781 } |
| 5782 return 0; | 5782 return 0; |
| 5783 } | 5783 } |
| 5784 | 5784 |
| 5785 #ifdef NSS_ENABLE_ECC |
| 5785 /* Inputs: | 5786 /* Inputs: |
| 5786 * key_len: Length of derived key to be generated. | 5787 * key_len: Length of derived key to be generated. |
| 5787 * SharedSecret: a shared secret that is the output of a key agreement primitiv
e. | 5788 * SharedSecret: a shared secret that is the output of a key agreement primitiv
e. |
| 5788 * SharedInfo: (Optional) some data shared by the entities computing the secret
key. | 5789 * SharedInfo: (Optional) some data shared by the entities computing the secret
key. |
| 5789 * SharedInfoLen: the length in octets of SharedInfo | 5790 * SharedInfoLen: the length in octets of SharedInfo |
| 5790 * Hash: The hash function to be used in the KDF | 5791 * Hash: The hash function to be used in the KDF |
| 5791 * HashLen: the length in octets of the output of Hash | 5792 * HashLen: the length in octets of the output of Hash |
| 5792 * Output: | 5793 * Output: |
| 5793 * key: Pointer to a buffer containing derived key, if return value is SECSucce
ss. | 5794 * key: Pointer to a buffer containing derived key, if return value is SECSucce
ss. |
| 5794 */ | 5795 */ |
| 5795 static CK_RV sftk_compute_ANSI_X9_63_kdf(CK_BYTE **key, CK_ULONG key_len, SECIte
m *SharedSecret, | 5796 static CK_RV sftk_compute_ANSI_X9_63_kdf(CK_BYTE **key, CK_ULONG key_len, SECIte
m *SharedSecret, |
| 5796 CK_BYTE_PTR SharedInfo, CK_ULONG SharedInfoLen, | 5797 CK_BYTE_PTR SharedInfo, CK_ULONG SharedInfoLen, |
| 5797 SECStatus Hash(unsigned char *, const unsigned char *, PRUint32)
, | 5798 SECStatus Hash(unsigned char *, const unsigned char *, PRUint32)
, |
| 5798 CK_ULONG HashLen) | 5799 CK_ULONG HashLen) |
| 5799 { | 5800 { |
| 5800 unsigned char *buffer = NULL, *output_buffer = NULL; | 5801 unsigned char *buffer = NULL, *output_buffer = NULL; |
| 5801 PRUint32 buffer_len, max_counter, i; | 5802 PRUint32 buffer_len, max_counter, i; |
| 5802 SECStatus rv; | 5803 SECStatus rv; |
| 5804 CK_RV crv; |
| 5803 | 5805 |
| 5804 /* Check that key_len isn't too long. The maximum key length could be | 5806 /* Check that key_len isn't too long. The maximum key length could be |
| 5805 * greatly increased if the code below did not limit the 4-byte counter | 5807 * greatly increased if the code below did not limit the 4-byte counter |
| 5806 * to a maximum value of 255. */ | 5808 * to a maximum value of 255. */ |
| 5807 if (key_len > 254 * HashLen) | 5809 if (key_len > 254 * HashLen) |
| 5808 » return SEC_ERROR_INVALID_ARGS; | 5810 » return CKR_ARGUMENTS_BAD; |
| 5809 | 5811 |
| 5810 if (SharedInfo == NULL) | 5812 if (SharedInfo == NULL) |
| 5811 SharedInfoLen = 0; | 5813 SharedInfoLen = 0; |
| 5812 | 5814 |
| 5813 buffer_len = SharedSecret->len + 4 + SharedInfoLen; | 5815 buffer_len = SharedSecret->len + 4 + SharedInfoLen; |
| 5814 buffer = (CK_BYTE *)PORT_Alloc(buffer_len); | 5816 buffer = (CK_BYTE *)PORT_Alloc(buffer_len); |
| 5815 if (buffer == NULL) { | 5817 if (buffer == NULL) { |
| 5816 » rv = SEC_ERROR_NO_MEMORY; | 5818 » crv = CKR_HOST_MEMORY; |
| 5817 goto loser; | 5819 goto loser; |
| 5818 } | 5820 } |
| 5819 | 5821 |
| 5820 max_counter = key_len/HashLen; | 5822 max_counter = key_len/HashLen; |
| 5821 if (key_len > max_counter * HashLen) | 5823 if (key_len > max_counter * HashLen) |
| 5822 max_counter++; | 5824 max_counter++; |
| 5823 | 5825 |
| 5824 output_buffer = (CK_BYTE *)PORT_Alloc(max_counter * HashLen); | 5826 output_buffer = (CK_BYTE *)PORT_Alloc(max_counter * HashLen); |
| 5825 if (output_buffer == NULL) { | 5827 if (output_buffer == NULL) { |
| 5826 » rv = SEC_ERROR_NO_MEMORY; | 5828 » crv = CKR_HOST_MEMORY; |
| 5827 goto loser; | 5829 goto loser; |
| 5828 } | 5830 } |
| 5829 | 5831 |
| 5830 /* Populate buffer with SharedSecret || Counter || [SharedInfo] | 5832 /* Populate buffer with SharedSecret || Counter || [SharedInfo] |
| 5831 * where Counter is 0x00000001 */ | 5833 * where Counter is 0x00000001 */ |
| 5832 PORT_Memcpy(buffer, SharedSecret->data, SharedSecret->len); | 5834 PORT_Memcpy(buffer, SharedSecret->data, SharedSecret->len); |
| 5833 buffer[SharedSecret->len] = 0; | 5835 buffer[SharedSecret->len] = 0; |
| 5834 buffer[SharedSecret->len + 1] = 0; | 5836 buffer[SharedSecret->len + 1] = 0; |
| 5835 buffer[SharedSecret->len + 2] = 0; | 5837 buffer[SharedSecret->len + 2] = 0; |
| 5836 buffer[SharedSecret->len + 3] = 1; | 5838 buffer[SharedSecret->len + 3] = 1; |
| 5837 if (SharedInfo) { | 5839 if (SharedInfo) { |
| 5838 PORT_Memcpy(&buffer[SharedSecret->len + 4], SharedInfo, SharedInfoLen); | 5840 PORT_Memcpy(&buffer[SharedSecret->len + 4], SharedInfo, SharedInfoLen); |
| 5839 } | 5841 } |
| 5840 | 5842 |
| 5841 for(i=0; i < max_counter; i++) { | 5843 for(i=0; i < max_counter; i++) { |
| 5842 rv = Hash(&output_buffer[i * HashLen], buffer, buffer_len); | 5844 rv = Hash(&output_buffer[i * HashLen], buffer, buffer_len); |
| 5843 » if (rv != SECSuccess) | 5845 » if (rv != SECSuccess) { |
| 5846 » /* 'Hash' should not fail. */ |
| 5847 » crv = CKR_FUNCTION_FAILED; |
| 5844 goto loser; | 5848 goto loser; |
| 5849 } |
| 5845 | 5850 |
| 5846 /* Increment counter (assumes max_counter < 255) */ | 5851 /* Increment counter (assumes max_counter < 255) */ |
| 5847 buffer[SharedSecret->len + 3]++; | 5852 buffer[SharedSecret->len + 3]++; |
| 5848 } | 5853 } |
| 5849 | 5854 |
| 5850 PORT_ZFree(buffer, buffer_len); | 5855 PORT_ZFree(buffer, buffer_len); |
| 5851 if (key_len < max_counter * HashLen) { | 5856 if (key_len < max_counter * HashLen) { |
| 5852 PORT_Memset(output_buffer + key_len, 0, max_counter * HashLen - key_len)
; | 5857 PORT_Memset(output_buffer + key_len, 0, max_counter * HashLen - key_len)
; |
| 5853 } | 5858 } |
| 5854 *key = output_buffer; | 5859 *key = output_buffer; |
| 5855 | 5860 |
| 5856 return SECSuccess; | 5861 return CKR_OK; |
| 5857 | 5862 |
| 5858 loser: | 5863 loser: |
| 5859 if (buffer) { | 5864 if (buffer) { |
| 5860 PORT_ZFree(buffer, buffer_len); | 5865 PORT_ZFree(buffer, buffer_len); |
| 5861 } | 5866 } |
| 5862 if (output_buffer) { | 5867 if (output_buffer) { |
| 5863 PORT_ZFree(output_buffer, max_counter * HashLen); | 5868 PORT_ZFree(output_buffer, max_counter * HashLen); |
| 5864 } | 5869 } |
| 5865 » return rv; | 5870 » return crv; |
| 5866 } | 5871 } |
| 5867 | 5872 |
| 5868 static CK_RV sftk_ANSI_X9_63_kdf(CK_BYTE **key, CK_ULONG key_len, | 5873 static CK_RV sftk_ANSI_X9_63_kdf(CK_BYTE **key, CK_ULONG key_len, |
| 5869 SECItem *SharedSecret, | 5874 SECItem *SharedSecret, |
| 5870 CK_BYTE_PTR SharedInfo, CK_ULONG SharedInfoLen, | 5875 CK_BYTE_PTR SharedInfo, CK_ULONG SharedInfoLen, |
| 5871 CK_EC_KDF_TYPE kdf) | 5876 CK_EC_KDF_TYPE kdf) |
| 5872 { | 5877 { |
| 5873 if (kdf == CKD_SHA1_KDF) | 5878 if (kdf == CKD_SHA1_KDF) |
| 5874 return sftk_compute_ANSI_X9_63_kdf(key, key_len, SharedSecret, SharedInf
o, | 5879 return sftk_compute_ANSI_X9_63_kdf(key, key_len, SharedSecret, SharedInf
o, |
| 5875 SharedInfoLen, SHA1_HashBuf, SHA1_LENGTH); | 5880 SharedInfoLen, SHA1_HashBuf, SHA1_LENGTH); |
| 5876 else if (kdf == CKD_SHA224_KDF) | 5881 else if (kdf == CKD_SHA224_KDF) |
| 5877 return sftk_compute_ANSI_X9_63_kdf(key, key_len, SharedSecret, SharedInf
o, | 5882 return sftk_compute_ANSI_X9_63_kdf(key, key_len, SharedSecret, SharedInf
o, |
| 5878 SharedInfoLen, SHA224_HashBuf, SHA224_LENGTH); | 5883 SharedInfoLen, SHA224_HashBuf, SHA224_LENGTH); |
| 5879 else if (kdf == CKD_SHA256_KDF) | 5884 else if (kdf == CKD_SHA256_KDF) |
| 5880 return sftk_compute_ANSI_X9_63_kdf(key, key_len, SharedSecret, SharedInf
o, | 5885 return sftk_compute_ANSI_X9_63_kdf(key, key_len, SharedSecret, SharedInf
o, |
| 5881 SharedInfoLen, SHA256_HashBuf, SHA256_LENGTH); | 5886 SharedInfoLen, SHA256_HashBuf, SHA256_LENGTH); |
| 5882 else if (kdf == CKD_SHA384_KDF) | 5887 else if (kdf == CKD_SHA384_KDF) |
| 5883 return sftk_compute_ANSI_X9_63_kdf(key, key_len, SharedSecret, SharedInf
o, | 5888 return sftk_compute_ANSI_X9_63_kdf(key, key_len, SharedSecret, SharedInf
o, |
| 5884 SharedInfoLen, SHA384_HashBuf, SHA384_LENGTH); | 5889 SharedInfoLen, SHA384_HashBuf, SHA384_LENGTH); |
| 5885 else if (kdf == CKD_SHA512_KDF) | 5890 else if (kdf == CKD_SHA512_KDF) |
| 5886 return sftk_compute_ANSI_X9_63_kdf(key, key_len, SharedSecret, SharedInf
o, | 5891 return sftk_compute_ANSI_X9_63_kdf(key, key_len, SharedSecret, SharedInf
o, |
| 5887 SharedInfoLen, SHA512_HashBuf, SHA512_LENGTH); | 5892 SharedInfoLen, SHA512_HashBuf, SHA512_LENGTH); |
| 5888 else | 5893 else |
| 5889 » return SEC_ERROR_INVALID_ALGORITHM; | 5894 » return CKR_MECHANISM_INVALID; |
| 5890 } | 5895 } |
| 5896 #endif |
| 5891 | 5897 |
| 5892 /* | 5898 /* |
| 5893 * SSL Key generation given pre master secret | 5899 * SSL Key generation given pre master secret |
| 5894 */ | 5900 */ |
| 5895 #define NUM_MIXERS 9 | 5901 #define NUM_MIXERS 9 |
| 5896 static const char * const mixers[NUM_MIXERS] = { | 5902 static const char * const mixers[NUM_MIXERS] = { |
| 5897 "A", | 5903 "A", |
| 5898 "BB", | 5904 "BB", |
| 5899 "CCC", | 5905 "CCC", |
| 5900 "DDDD", | 5906 "DDDD", |
| (...skipping 1031 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6932 if (mechParams->kdf == CKD_NULL) { | 6938 if (mechParams->kdf == CKD_NULL) { |
| 6933 /* | 6939 /* |
| 6934 * tmp is the raw data created by ECDH_Derive, | 6940 * tmp is the raw data created by ECDH_Derive, |
| 6935 * secret and secretlen are the values we will | 6941 * secret and secretlen are the values we will |
| 6936 * eventually pass as our generated key. | 6942 * eventually pass as our generated key. |
| 6937 */ | 6943 */ |
| 6938 secret = tmp.data; | 6944 secret = tmp.data; |
| 6939 secretlen = tmp.len; | 6945 secretlen = tmp.len; |
| 6940 } else { | 6946 } else { |
| 6941 secretlen = keySize; | 6947 secretlen = keySize; |
| 6942 » rv = sftk_ANSI_X9_63_kdf(&secret, keySize, | 6948 » crv = sftk_ANSI_X9_63_kdf(&secret, keySize, |
| 6943 &tmp, mechParams->pSharedData, | 6949 &tmp, mechParams->pSharedData, |
| 6944 mechParams->ulSharedDataLen, mechParams->kdf); | 6950 mechParams->ulSharedDataLen, mechParams->kdf); |
| 6945 PORT_ZFree(tmp.data, tmp.len); | 6951 PORT_ZFree(tmp.data, tmp.len); |
| 6946 » if (rv != SECSuccess) { | 6952 » if (crv != CKR_OK) { |
| 6947 » » crv = CKR_HOST_MEMORY; | |
| 6948 break; | 6953 break; |
| 6949 } | 6954 } |
| 6950 tmp.data = secret; | 6955 tmp.data = secret; |
| 6951 tmp.len = secretlen; | 6956 tmp.len = secretlen; |
| 6952 } | 6957 } |
| 6953 | 6958 |
| 6954 /* | 6959 /* |
| 6955 * if keySize is supplied, then we are generating a key of a specific | 6960 * if keySize is supplied, then we are generating a key of a specific |
| 6956 * length. This is done by taking the least significant 'keySize' | 6961 * length. This is done by taking the least significant 'keySize' |
| 6957 * bytes from the unsigned value calculated by ECDH. Note: this may | 6962 * bytes from the unsigned value calculated by ECDH. Note: this may |
| (...skipping 446 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7404 att = sftk_FindAttribute(key,CKA_VALUE); | 7409 att = sftk_FindAttribute(key,CKA_VALUE); |
| 7405 sftk_FreeObject(key); | 7410 sftk_FreeObject(key); |
| 7406 if (!att) { | 7411 if (!att) { |
| 7407 return CKR_KEY_HANDLE_INVALID; | 7412 return CKR_KEY_HANDLE_INVALID; |
| 7408 } | 7413 } |
| 7409 crv = NSC_DigestUpdate(hSession,(CK_BYTE_PTR)att->attrib.pValue, | 7414 crv = NSC_DigestUpdate(hSession,(CK_BYTE_PTR)att->attrib.pValue, |
| 7410 att->attrib.ulValueLen); | 7415 att->attrib.ulValueLen); |
| 7411 sftk_FreeAttribute(att); | 7416 sftk_FreeAttribute(att); |
| 7412 return crv; | 7417 return crv; |
| 7413 } | 7418 } |
| OLD | NEW |