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. |
11 * It can also support Private Key ops for imported Private keys. It does | 11 * It can also support Private Key ops for imported Private keys. It does |
12 * not have any token storage. | 12 * not have any token storage. |
13 * slot 2 is our private key support. It requires a login before use. It | 13 * slot 2 is our private key support. It requires a login before use. It |
14 * can store Private Keys and Certs as token objects. Currently only private | 14 * can store Private Keys and Certs as token objects. Currently only private |
15 * keys and their associated Certificates are saved on the token. | 15 * keys and their associated Certificates are saved on the token. |
16 * | 16 * |
17 * In this implementation, session objects are only visible to the session | 17 * In this implementation, session objects are only visible to the session |
18 * that created or generated them. | 18 * that created or generated them. |
19 */ | 19 */ |
20 #include "seccomon.h" | 20 #include "seccomon.h" |
21 #include "secitem.h" | 21 #include "secitem.h" |
22 #include "secport.h" | 22 #include "secport.h" |
23 #include "blapi.h" | 23 #include "blapi.h" |
24 #include "pkcs11.h" | 24 #include "pkcs11.h" |
25 #include "pkcs11i.h" | 25 #include "pkcs11i.h" |
26 #include "lowkeyi.h" | 26 #include "lowkeyi.h" |
27 #include "sechash.h" | |
28 #include "secder.h" | 27 #include "secder.h" |
29 #include "secdig.h" | 28 #include "secdig.h" |
30 #include "lowpbe.h" /* We do PBE below */ | 29 #include "lowpbe.h" /* We do PBE below */ |
31 #include "pkcs11t.h" | 30 #include "pkcs11t.h" |
32 #include "secoid.h" | 31 #include "secoid.h" |
33 #include "alghmac.h" | 32 #include "alghmac.h" |
34 #include "softoken.h" | 33 #include "softoken.h" |
35 #include "secasn1.h" | 34 #include "secasn1.h" |
36 #include "secerr.h" | 35 #include "secerr.h" |
37 | 36 |
(...skipping 2012 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2050 break; | 2049 break; |
2051 } | 2050 } |
2052 privKey = sftk_GetPrivKey(key,CKK_DSA,&crv); | 2051 privKey = sftk_GetPrivKey(key,CKK_DSA,&crv); |
2053 if (privKey == NULL) { | 2052 if (privKey == NULL) { |
2054 break; | 2053 break; |
2055 } | 2054 } |
2056 context->cipherInfo = privKey; | 2055 context->cipherInfo = privKey; |
2057 context->update = (SFTKCipher) nsc_DSA_Sign_Stub; | 2056 context->update = (SFTKCipher) nsc_DSA_Sign_Stub; |
2058 context->destroy = (privKey == key->objectInfo) ? | 2057 context->destroy = (privKey == key->objectInfo) ? |
2059 (SFTKDestroy) sftk_Null:(SFTKDestroy)sftk_FreePrivKey; | 2058 (SFTKDestroy) sftk_Null:(SFTKDestroy)sftk_FreePrivKey; |
2060 » context->maxLen = DSA_SIGNATURE_LEN; | 2059 » context->maxLen = DSA_MAX_SIGNATURE_LEN; |
2061 | 2060 |
2062 break; | 2061 break; |
2063 | 2062 |
2064 #ifdef NSS_ENABLE_ECC | 2063 #ifdef NSS_ENABLE_ECC |
2065 case CKM_ECDSA_SHA1: | 2064 case CKM_ECDSA_SHA1: |
2066 context->multi = PR_TRUE; | 2065 context->multi = PR_TRUE; |
2067 crv = sftk_doSubSHA1(context); | 2066 crv = sftk_doSubSHA1(context); |
2068 if (crv != CKR_OK) break; | 2067 if (crv != CKR_OK) break; |
2069 /* fall through */ | 2068 /* fall through */ |
2070 case CKM_ECDSA: | 2069 case CKM_ECDSA: |
(...skipping 827 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2898 | 2897 |
2899 if (iv.data) { | 2898 if (iv.data) { |
2900 if (pbe_params && pbe_params->pInitVector != NULL) { | 2899 if (pbe_params && pbe_params->pInitVector != NULL) { |
2901 PORT_Memcpy(pbe_params->pInitVector, iv.data, iv.len); | 2900 PORT_Memcpy(pbe_params->pInitVector, iv.data, iv.len); |
2902 } | 2901 } |
2903 PORT_Free(iv.data); | 2902 PORT_Free(iv.data); |
2904 } | 2903 } |
2905 | 2904 |
2906 return CKR_OK; | 2905 return CKR_OK; |
2907 } | 2906 } |
| 2907 |
| 2908 /* |
| 2909 * this is coded for "full" support. These selections will be limitted to |
| 2910 * the official subset by freebl. |
| 2911 */ |
| 2912 static unsigned int |
| 2913 sftk_GetSubPrimeFromPrime(unsigned int primeBits) |
| 2914 { |
| 2915 if (primeBits <= 1024) { |
| 2916 return 160; |
| 2917 } else if (primeBits <= 2048) { |
| 2918 return 224; |
| 2919 } else if (primeBits <= 3072) { |
| 2920 return 256; |
| 2921 } else if (primeBits <= 7680) { |
| 2922 return 384; |
| 2923 } else { |
| 2924 return 512; |
| 2925 } |
| 2926 } |
| 2927 |
2908 static CK_RV | 2928 static CK_RV |
2909 nsc_parameter_gen(CK_KEY_TYPE key_type, SFTKObject *key) | 2929 nsc_parameter_gen(CK_KEY_TYPE key_type, SFTKObject *key) |
2910 { | 2930 { |
2911 SFTKAttribute *attribute; | 2931 SFTKAttribute *attribute; |
2912 CK_ULONG counter; | 2932 CK_ULONG counter; |
2913 unsigned int seedBits = 0; | 2933 unsigned int seedBits = 0; |
| 2934 unsigned int subprimeBits = 0; |
2914 unsigned int primeBits; | 2935 unsigned int primeBits; |
2915 unsigned int j; | 2936 unsigned int j = 8; /* default to 1024 bits */ |
2916 CK_RV crv = CKR_OK; | 2937 CK_RV crv = CKR_OK; |
2917 PQGParams *params = NULL; | 2938 PQGParams *params = NULL; |
2918 PQGVerify *vfy = NULL; | 2939 PQGVerify *vfy = NULL; |
2919 SECStatus rv; | 2940 SECStatus rv; |
2920 | 2941 |
2921 attribute = sftk_FindAttribute(key, CKA_PRIME_BITS); | 2942 attribute = sftk_FindAttribute(key, CKA_PRIME_BITS); |
2922 if (attribute == NULL) { | 2943 if (attribute == NULL) { |
2923 return CKR_TEMPLATE_INCOMPLETE; | 2944 return CKR_TEMPLATE_INCOMPLETE; |
2924 } | 2945 } |
2925 primeBits = (unsigned int) *(CK_ULONG *)attribute->attrib.pValue; | 2946 primeBits = (unsigned int) *(CK_ULONG *)attribute->attrib.pValue; |
2926 sftk_FreeAttribute(attribute); | 2947 sftk_FreeAttribute(attribute); |
2927 j = PQG_PBITS_TO_INDEX(primeBits); | 2948 if (primeBits < 1024) { |
2928 if (j == (unsigned int)-1) { | 2949 » j = PQG_PBITS_TO_INDEX(primeBits); |
2929 » return CKR_ATTRIBUTE_VALUE_INVALID; | 2950 » if (j == (unsigned int)-1) { |
| 2951 » return CKR_ATTRIBUTE_VALUE_INVALID; |
| 2952 » } |
2930 } | 2953 } |
2931 | 2954 |
2932 attribute = sftk_FindAttribute(key, CKA_NETSCAPE_PQG_SEED_BITS); | 2955 attribute = sftk_FindAttribute(key, CKA_NETSCAPE_PQG_SEED_BITS); |
2933 if (attribute != NULL) { | 2956 if (attribute != NULL) { |
2934 seedBits = (unsigned int) *(CK_ULONG *)attribute->attrib.pValue; | 2957 seedBits = (unsigned int) *(CK_ULONG *)attribute->attrib.pValue; |
2935 sftk_FreeAttribute(attribute); | 2958 sftk_FreeAttribute(attribute); |
2936 } | 2959 } |
2937 | 2960 |
| 2961 attribute = sftk_FindAttribute(key, CKA_SUBPRIME_BITS); |
| 2962 if (attribute != NULL) { |
| 2963 subprimeBits = (unsigned int) *(CK_ULONG *)attribute->attrib.pValue; |
| 2964 sftk_FreeAttribute(attribute); |
| 2965 } |
| 2966 |
2938 sftk_DeleteAttributeType(key,CKA_PRIME_BITS); | 2967 sftk_DeleteAttributeType(key,CKA_PRIME_BITS); |
| 2968 sftk_DeleteAttributeType(key,CKA_SUBPRIME_BITS); |
2939 sftk_DeleteAttributeType(key,CKA_NETSCAPE_PQG_SEED_BITS); | 2969 sftk_DeleteAttributeType(key,CKA_NETSCAPE_PQG_SEED_BITS); |
2940 | 2970 |
2941 if (seedBits == 0) { | 2971 /* use the old PQG interface if we have old input data */ |
2942 » rv = PQG_ParamGen(j, ¶ms, &vfy); | 2972 if ((primeBits < 1024) || ((primeBits == 1024) && (subprimeBits == 0))) { |
| 2973 » if (seedBits == 0) { |
| 2974 » rv = PQG_ParamGen(j, ¶ms, &vfy); |
| 2975 » } else { |
| 2976 » rv = PQG_ParamGenSeedLen(j,seedBits/8, ¶ms, &vfy); |
| 2977 » } |
2943 } else { | 2978 } else { |
2944 » rv = PQG_ParamGenSeedLen(j,seedBits/8, ¶ms, &vfy); | 2979 » if (subprimeBits == 0) { |
| 2980 » subprimeBits = sftk_GetSubPrimeFromPrime(primeBits); |
| 2981 } |
| 2982 » if (seedBits == 0) { |
| 2983 » seedBits = primeBits; |
| 2984 » } |
| 2985 » rv = PQG_ParamGenV2(primeBits, subprimeBits, seedBits/8, ¶ms, &vfy); |
2945 } | 2986 } |
| 2987 |
| 2988 |
2946 | 2989 |
2947 if (rv != SECSuccess) { | 2990 if (rv != SECSuccess) { |
2948 if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) { | 2991 if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) { |
2949 sftk_fatalError = PR_TRUE; | 2992 sftk_fatalError = PR_TRUE; |
2950 } | 2993 } |
2951 return sftk_MapCryptError(PORT_GetError()); | 2994 return sftk_MapCryptError(PORT_GetError()); |
2952 } | 2995 } |
2953 crv = sftk_AddAttributeType(key,CKA_PRIME, | 2996 crv = sftk_AddAttributeType(key,CKA_PRIME, |
2954 params->prime.data, params->prime.len); | 2997 params->prime.data, params->prime.len); |
2955 if (crv != CKR_OK) goto loser; | 2998 if (crv != CKR_OK) goto loser; |
(...skipping 496 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3452 * For sign/verify: CKK_RSA => CKM_RSA_PKCS | 3495 * For sign/verify: CKK_RSA => CKM_RSA_PKCS |
3453 * CKK_DSA => CKM_DSA | 3496 * CKK_DSA => CKM_DSA |
3454 * CKK_EC => CKM_ECDSA | 3497 * CKK_EC => CKM_ECDSA |
3455 * others => CKM_INVALID_MECHANISM | 3498 * others => CKM_INVALID_MECHANISM |
3456 * | 3499 * |
3457 * None of these mechanisms has a parameter. | 3500 * None of these mechanisms has a parameter. |
3458 */ | 3501 */ |
3459 CK_MECHANISM mech = {0, NULL, 0}; | 3502 CK_MECHANISM mech = {0, NULL, 0}; |
3460 | 3503 |
3461 CK_ULONG modulusLen; | 3504 CK_ULONG modulusLen; |
| 3505 CK_ULONG subPrimeLen; |
3462 PRBool isEncryptable = PR_FALSE; | 3506 PRBool isEncryptable = PR_FALSE; |
3463 PRBool canSignVerify = PR_FALSE; | 3507 PRBool canSignVerify = PR_FALSE; |
3464 PRBool isDerivable = PR_FALSE; | 3508 PRBool isDerivable = PR_FALSE; |
3465 CK_RV crv; | 3509 CK_RV crv; |
3466 | 3510 |
3467 /* Variables used for Encrypt/Decrypt functions. */ | 3511 /* Variables used for Encrypt/Decrypt functions. */ |
3468 unsigned char *known_message = (unsigned char *)"Known Crypto Message"; | 3512 unsigned char *known_message = (unsigned char *)"Known Crypto Message"; |
3469 unsigned char plaintext[PAIRWISE_MESSAGE_LENGTH]; | 3513 unsigned char plaintext[PAIRWISE_MESSAGE_LENGTH]; |
3470 CK_ULONG bytes_decrypted; | 3514 CK_ULONG bytes_decrypted; |
3471 unsigned char *ciphertext; | 3515 unsigned char *ciphertext; |
3472 unsigned char *text_compared; | 3516 unsigned char *text_compared; |
3473 CK_ULONG bytes_encrypted; | 3517 CK_ULONG bytes_encrypted; |
3474 CK_ULONG bytes_compared; | 3518 CK_ULONG bytes_compared; |
| 3519 CK_ULONG pairwise_digest_length = PAIRWISE_DIGEST_LENGTH; |
3475 | 3520 |
3476 /* Variables used for Signature/Verification functions. */ | 3521 /* Variables used for Signature/Verification functions. */ |
3477 /* always uses SHA-1 digest */ | 3522 /* Must be at least 256 bits for DSA2 digest */ |
3478 unsigned char *known_digest = (unsigned char *)"Mozilla Rules World!"; | 3523 unsigned char *known_digest = (unsigned char *) |
| 3524 » » » » "Mozilla Rules the World through NSS!"; |
3479 unsigned char *signature; | 3525 unsigned char *signature; |
3480 CK_ULONG signature_length; | 3526 CK_ULONG signature_length; |
3481 | 3527 |
3482 if (keyType == CKK_RSA) { | 3528 if (keyType == CKK_RSA) { |
3483 SFTKAttribute *attribute; | 3529 SFTKAttribute *attribute; |
3484 | 3530 |
3485 /* Get modulus length of private key. */ | 3531 /* Get modulus length of private key. */ |
3486 attribute = sftk_FindAttribute(privateKey, CKA_MODULUS); | 3532 attribute = sftk_FindAttribute(privateKey, CKA_MODULUS); |
3487 if (attribute == NULL) { | 3533 if (attribute == NULL) { |
3488 return CKR_DEVICE_ERROR; | 3534 return CKR_DEVICE_ERROR; |
3489 } | 3535 } |
3490 modulusLen = attribute->attrib.ulValueLen; | 3536 modulusLen = attribute->attrib.ulValueLen; |
3491 if (*(unsigned char *)attribute->attrib.pValue == 0) { | 3537 if (*(unsigned char *)attribute->attrib.pValue == 0) { |
3492 modulusLen--; | 3538 modulusLen--; |
3493 } | 3539 } |
3494 sftk_FreeAttribute(attribute); | 3540 sftk_FreeAttribute(attribute); |
| 3541 } else if (keyType == CKK_DSA) { |
| 3542 SFTKAttribute *attribute; |
| 3543 |
| 3544 /* Get subprime length of private key. */ |
| 3545 attribute = sftk_FindAttribute(privateKey, CKA_SUBPRIME); |
| 3546 if (attribute == NULL) { |
| 3547 return CKR_DEVICE_ERROR; |
| 3548 } |
| 3549 subPrimeLen = attribute->attrib.ulValueLen; |
| 3550 if (subPrimeLen > 1 && *(unsigned char *)attribute->attrib.pValue == 0)
{ |
| 3551 subPrimeLen--; |
| 3552 } |
| 3553 sftk_FreeAttribute(attribute); |
3495 } | 3554 } |
3496 | 3555 |
3497 /**************************************************/ | 3556 /**************************************************/ |
3498 /* Pairwise Consistency Check of Encrypt/Decrypt. */ | 3557 /* Pairwise Consistency Check of Encrypt/Decrypt. */ |
3499 /**************************************************/ | 3558 /**************************************************/ |
3500 | 3559 |
3501 isEncryptable = sftk_isTrue(privateKey, CKA_DECRYPT); | 3560 isEncryptable = sftk_isTrue(privateKey, CKA_DECRYPT); |
3502 | 3561 |
3503 /* | 3562 /* |
3504 * If the decryption attribute is set, attempt to encrypt | 3563 * If the decryption attribute is set, attempt to encrypt |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3610 canSignVerify = sftk_isTrue(privateKey, CKA_SIGN); | 3669 canSignVerify = sftk_isTrue(privateKey, CKA_SIGN); |
3611 | 3670 |
3612 if (canSignVerify) { | 3671 if (canSignVerify) { |
3613 /* Determine length of signature. */ | 3672 /* Determine length of signature. */ |
3614 switch (keyType) { | 3673 switch (keyType) { |
3615 case CKK_RSA: | 3674 case CKK_RSA: |
3616 signature_length = modulusLen; | 3675 signature_length = modulusLen; |
3617 mech.mechanism = CKM_RSA_PKCS; | 3676 mech.mechanism = CKM_RSA_PKCS; |
3618 break; | 3677 break; |
3619 case CKK_DSA: | 3678 case CKK_DSA: |
3620 » signature_length = DSA_SIGNATURE_LEN; | 3679 » signature_length = DSA_MAX_SIGNATURE_LEN; |
| 3680 » pairwise_digest_length = subPrimeLen; |
3621 mech.mechanism = CKM_DSA; | 3681 mech.mechanism = CKM_DSA; |
3622 break; | 3682 break; |
3623 #ifdef NSS_ENABLE_ECC | 3683 #ifdef NSS_ENABLE_ECC |
3624 case CKK_EC: | 3684 case CKK_EC: |
3625 signature_length = MAX_ECKEY_LEN * 2; | 3685 signature_length = MAX_ECKEY_LEN * 2; |
3626 mech.mechanism = CKM_ECDSA; | 3686 mech.mechanism = CKM_ECDSA; |
3627 break; | 3687 break; |
3628 #endif | 3688 #endif |
3629 default: | 3689 default: |
3630 return CKR_DEVICE_ERROR; | 3690 return CKR_DEVICE_ERROR; |
3631 } | 3691 } |
3632 | 3692 |
3633 /* Allocate space for signature data. */ | 3693 /* Allocate space for signature data. */ |
3634 signature = (unsigned char *) PORT_ZAlloc(signature_length); | 3694 signature = (unsigned char *) PORT_ZAlloc(signature_length); |
3635 if (signature == NULL) { | 3695 if (signature == NULL) { |
3636 return CKR_HOST_MEMORY; | 3696 return CKR_HOST_MEMORY; |
3637 } | 3697 } |
3638 | 3698 |
3639 /* Sign the known hash using the private key. */ | 3699 /* Sign the known hash using the private key. */ |
3640 crv = NSC_SignInit(hSession, &mech, privateKey->handle); | 3700 crv = NSC_SignInit(hSession, &mech, privateKey->handle); |
3641 if (crv != CKR_OK) { | 3701 if (crv != CKR_OK) { |
3642 PORT_Free(signature); | 3702 PORT_Free(signature); |
3643 return crv; | 3703 return crv; |
3644 } | 3704 } |
3645 | 3705 |
3646 crv = NSC_Sign(hSession, | 3706 crv = NSC_Sign(hSession, |
3647 known_digest, | 3707 known_digest, |
3648 » » PAIRWISE_DIGEST_LENGTH, | 3708 » » pairwise_digest_length, |
3649 signature, | 3709 signature, |
3650 &signature_length); | 3710 &signature_length); |
3651 if (crv != CKR_OK) { | 3711 if (crv != CKR_OK) { |
3652 PORT_Free(signature); | 3712 PORT_Free(signature); |
3653 return crv; | 3713 return crv; |
3654 } | 3714 } |
3655 | 3715 |
3656 /* Verify the known hash using the public key. */ | 3716 /* Verify the known hash using the public key. */ |
3657 crv = NSC_VerifyInit(hSession, &mech, publicKey->handle); | 3717 crv = NSC_VerifyInit(hSession, &mech, publicKey->handle); |
3658 if (crv != CKR_OK) { | 3718 if (crv != CKR_OK) { |
3659 PORT_Free(signature); | 3719 PORT_Free(signature); |
3660 return crv; | 3720 return crv; |
3661 } | 3721 } |
3662 | 3722 |
3663 crv = NSC_Verify(hSession, | 3723 crv = NSC_Verify(hSession, |
3664 known_digest, | 3724 known_digest, |
3665 » » » PAIRWISE_DIGEST_LENGTH, | 3725 » » » pairwise_digest_length, |
3666 signature, | 3726 signature, |
3667 signature_length); | 3727 signature_length); |
3668 | 3728 |
3669 /* Free signature data. */ | 3729 /* Free signature data. */ |
3670 PORT_Free(signature); | 3730 PORT_Free(signature); |
3671 | 3731 |
3672 if ((crv == CKR_SIGNATURE_LEN_RANGE) || | 3732 if ((crv == CKR_SIGNATURE_LEN_RANGE) || |
3673 (crv == CKR_SIGNATURE_INVALID)) { | 3733 (crv == CKR_SIGNATURE_INVALID)) { |
3674 return CKR_GENERAL_ERROR; | 3734 return CKR_GENERAL_ERROR; |
3675 } | 3735 } |
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3938 } | 3998 } |
3939 crv = sftk_AddAttributeType(privateKey,CKA_BASE, | 3999 crv = sftk_AddAttributeType(privateKey,CKA_BASE, |
3940 sftk_item_expand(&pqgParam.base)); | 4000 sftk_item_expand(&pqgParam.base)); |
3941 if (crv != CKR_OK) { | 4001 if (crv != CKR_OK) { |
3942 PORT_Free(pqgParam.prime.data); | 4002 PORT_Free(pqgParam.prime.data); |
3943 PORT_Free(pqgParam.subPrime.data); | 4003 PORT_Free(pqgParam.subPrime.data); |
3944 PORT_Free(pqgParam.base.data); | 4004 PORT_Free(pqgParam.base.data); |
3945 break; | 4005 break; |
3946 } | 4006 } |
3947 | 4007 |
| 4008 /* |
| 4009 * these are checked by DSA_NewKey |
| 4010 */ |
3948 bitSize = sftk_GetLengthInBits(pqgParam.subPrime.data, | 4011 bitSize = sftk_GetLengthInBits(pqgParam.subPrime.data, |
3949 pqgParam.subPrime.len); | 4012 pqgParam.subPrime.len); |
3950 if (bitSize != DSA_Q_BITS) { | 4013 if ((bitSize < DSA_MIN_Q_BITS) || (bitSize > DSA_MAX_Q_BITS)) { |
3951 crv = CKR_TEMPLATE_INCOMPLETE; | 4014 crv = CKR_TEMPLATE_INCOMPLETE; |
3952 PORT_Free(pqgParam.prime.data); | 4015 PORT_Free(pqgParam.prime.data); |
3953 PORT_Free(pqgParam.subPrime.data); | 4016 PORT_Free(pqgParam.subPrime.data); |
3954 PORT_Free(pqgParam.base.data); | 4017 PORT_Free(pqgParam.base.data); |
3955 break; | 4018 break; |
3956 } | 4019 } |
3957 bitSize = sftk_GetLengthInBits(pqgParam.prime.data,pqgParam.prime.len); | 4020 bitSize = sftk_GetLengthInBits(pqgParam.prime.data,pqgParam.prime.len); |
3958 if ((bitSize < DSA_MIN_P_BITS) || (bitSize > DSA_MAX_P_BITS)) { | 4021 if ((bitSize < DSA_MIN_P_BITS) || (bitSize > DSA_MAX_P_BITS)) { |
3959 crv = CKR_TEMPLATE_INCOMPLETE; | 4022 crv = CKR_TEMPLATE_INCOMPLETE; |
3960 PORT_Free(pqgParam.prime.data); | 4023 PORT_Free(pqgParam.prime.data); |
3961 PORT_Free(pqgParam.subPrime.data); | 4024 PORT_Free(pqgParam.subPrime.data); |
3962 PORT_Free(pqgParam.base.data); | 4025 PORT_Free(pqgParam.base.data); |
3963 break; | 4026 break; |
3964 } | 4027 } |
3965 bitSize = sftk_GetLengthInBits(pqgParam.base.data,pqgParam.base.len); | 4028 bitSize = sftk_GetLengthInBits(pqgParam.base.data,pqgParam.base.len); |
3966 if ((bitSize < 1) || (bitSize > DSA_MAX_P_BITS)) { | 4029 if ((bitSize < 2) || (bitSize > DSA_MAX_P_BITS)) { |
3967 crv = CKR_TEMPLATE_INCOMPLETE; | 4030 crv = CKR_TEMPLATE_INCOMPLETE; |
3968 PORT_Free(pqgParam.prime.data); | 4031 PORT_Free(pqgParam.prime.data); |
3969 PORT_Free(pqgParam.subPrime.data); | 4032 PORT_Free(pqgParam.subPrime.data); |
3970 PORT_Free(pqgParam.base.data); | 4033 PORT_Free(pqgParam.base.data); |
3971 break; | 4034 break; |
3972 } | 4035 } |
3973 | 4036 |
3974 /* Generate the key */ | 4037 /* Generate the key */ |
3975 rv = DSA_NewKey(&pqgParam, &dsaPriv); | 4038 rv = DSA_NewKey(&pqgParam, &dsaPriv); |
3976 | 4039 |
(...skipping 1081 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5058 return 16; | 5121 return 16; |
5059 case CKK_DES3: | 5122 case CKK_DES3: |
5060 return 24; | 5123 return 24; |
5061 /* IDEA and CAST need to be added */ | 5124 /* IDEA and CAST need to be added */ |
5062 default: | 5125 default: |
5063 break; | 5126 break; |
5064 } | 5127 } |
5065 return 0; | 5128 return 0; |
5066 } | 5129 } |
5067 | 5130 |
| 5131 /* Inputs: |
| 5132 * key_len: Length of derived key to be generated. |
| 5133 * SharedSecret: a shared secret that is the output of a key agreement primitiv
e. |
| 5134 * SharedInfo: (Optional) some data shared by the entities computing the secret
key. |
| 5135 * SharedInfoLen: the length in octets of SharedInfo |
| 5136 * Hash: The hash function to be used in the KDF |
| 5137 * HashLen: the length in octets of the output of Hash |
| 5138 * Output: |
| 5139 * key: Pointer to a buffer containing derived key, if return value is SECSucce
ss. |
| 5140 */ |
| 5141 static CK_RV sftk_compute_ANSI_X9_63_kdf(CK_BYTE **key, CK_ULONG key_len, SECIte
m *SharedSecret, |
| 5142 CK_BYTE_PTR SharedInfo, CK_ULONG SharedInfoLen, |
| 5143 SECStatus Hash(unsigned char *, const unsigned char *, uint32), |
| 5144 CK_ULONG HashLen) |
| 5145 { |
| 5146 unsigned char *buffer = NULL, *output_buffer = NULL; |
| 5147 uint32 buffer_len, max_counter, i; |
| 5148 SECStatus rv; |
| 5149 |
| 5150 /* Check that key_len isn't too long. The maximum key length could be |
| 5151 * greatly increased if the code below did not limit the 4-byte counter |
| 5152 * to a maximum value of 255. */ |
| 5153 if (key_len > 254 * HashLen) |
| 5154 return SEC_ERROR_INVALID_ARGS; |
| 5155 |
| 5156 if (SharedInfo == NULL) |
| 5157 SharedInfoLen = 0; |
| 5158 |
| 5159 buffer_len = SharedSecret->len + 4 + SharedInfoLen; |
| 5160 buffer = (CK_BYTE *)PORT_Alloc(buffer_len); |
| 5161 if (buffer == NULL) { |
| 5162 rv = SEC_ERROR_NO_MEMORY; |
| 5163 goto loser; |
| 5164 } |
| 5165 |
| 5166 max_counter = key_len/HashLen; |
| 5167 if (key_len > max_counter * HashLen) |
| 5168 max_counter++; |
| 5169 |
| 5170 output_buffer = (CK_BYTE *)PORT_Alloc(max_counter * HashLen); |
| 5171 if (output_buffer == NULL) { |
| 5172 rv = SEC_ERROR_NO_MEMORY; |
| 5173 goto loser; |
| 5174 } |
| 5175 |
| 5176 /* Populate buffer with SharedSecret || Counter || [SharedInfo] |
| 5177 * where Counter is 0x00000001 */ |
| 5178 PORT_Memcpy(buffer, SharedSecret->data, SharedSecret->len); |
| 5179 buffer[SharedSecret->len] = 0; |
| 5180 buffer[SharedSecret->len + 1] = 0; |
| 5181 buffer[SharedSecret->len + 2] = 0; |
| 5182 buffer[SharedSecret->len + 3] = 1; |
| 5183 if (SharedInfo) { |
| 5184 PORT_Memcpy(&buffer[SharedSecret->len + 4], SharedInfo, SharedInfoLen); |
| 5185 } |
| 5186 |
| 5187 for(i=0; i < max_counter; i++) { |
| 5188 rv = Hash(&output_buffer[i * HashLen], buffer, buffer_len); |
| 5189 if (rv != SECSuccess) |
| 5190 goto loser; |
| 5191 |
| 5192 /* Increment counter (assumes max_counter < 255) */ |
| 5193 buffer[SharedSecret->len + 3]++; |
| 5194 } |
| 5195 |
| 5196 PORT_ZFree(buffer, buffer_len); |
| 5197 if (key_len < max_counter * HashLen) { |
| 5198 PORT_Memset(output_buffer + key_len, 0, max_counter * HashLen - key_len)
; |
| 5199 } |
| 5200 *key = output_buffer; |
| 5201 |
| 5202 return SECSuccess; |
| 5203 |
| 5204 loser: |
| 5205 if (buffer) { |
| 5206 PORT_ZFree(buffer, buffer_len); |
| 5207 } |
| 5208 if (output_buffer) { |
| 5209 PORT_ZFree(output_buffer, max_counter * HashLen); |
| 5210 } |
| 5211 return rv; |
| 5212 } |
| 5213 |
| 5214 static CK_RV sftk_ANSI_X9_63_kdf(CK_BYTE **key, CK_ULONG key_len, |
| 5215 SECItem *SharedSecret, |
| 5216 CK_BYTE_PTR SharedInfo, CK_ULONG SharedInfoLen, |
| 5217 CK_EC_KDF_TYPE kdf) |
| 5218 { |
| 5219 if (kdf == CKD_SHA1_KDF) |
| 5220 return sftk_compute_ANSI_X9_63_kdf(key, key_len, SharedSecret, SharedInf
o, |
| 5221 SharedInfoLen, SHA1_HashBuf, SHA1_LENGTH); |
| 5222 else if (kdf == CKD_SHA224_KDF) |
| 5223 return sftk_compute_ANSI_X9_63_kdf(key, key_len, SharedSecret, SharedInf
o, |
| 5224 SharedInfoLen, SHA224_HashBuf, SHA224_LENGTH); |
| 5225 else if (kdf == CKD_SHA256_KDF) |
| 5226 return sftk_compute_ANSI_X9_63_kdf(key, key_len, SharedSecret, SharedInf
o, |
| 5227 SharedInfoLen, SHA256_HashBuf, SHA256_LENGTH); |
| 5228 else if (kdf == CKD_SHA384_KDF) |
| 5229 return sftk_compute_ANSI_X9_63_kdf(key, key_len, SharedSecret, SharedInf
o, |
| 5230 SharedInfoLen, SHA384_HashBuf, SHA384_LENGTH); |
| 5231 else if (kdf == CKD_SHA512_KDF) |
| 5232 return sftk_compute_ANSI_X9_63_kdf(key, key_len, SharedSecret, SharedInf
o, |
| 5233 SharedInfoLen, SHA512_HashBuf, SHA512_LENGTH); |
| 5234 else |
| 5235 return SEC_ERROR_INVALID_ALGORITHM; |
| 5236 } |
| 5237 |
5068 /* | 5238 /* |
5069 * SSL Key generation given pre master secret | 5239 * SSL Key generation given pre master secret |
5070 */ | 5240 */ |
5071 #define NUM_MIXERS 9 | 5241 #define NUM_MIXERS 9 |
5072 static const char * const mixers[NUM_MIXERS] = { | 5242 static const char * const mixers[NUM_MIXERS] = { |
5073 "A", | 5243 "A", |
5074 "BB", | 5244 "BB", |
5075 "CCC", | 5245 "CCC", |
5076 "DDDD", | 5246 "DDDD", |
5077 "EEEEE", | 5247 "EEEEE", |
(...skipping 808 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5886 MD2_DestroyContext(md2, PR_TRUE); | 6056 MD2_DestroyContext(md2, PR_TRUE); |
5887 | 6057 |
5888 crv = sftk_forceAttribute (key,CKA_VALUE,key_block,keySize); | 6058 crv = sftk_forceAttribute (key,CKA_VALUE,key_block,keySize); |
5889 break; | 6059 break; |
5890 case CKM_MD5_KEY_DERIVATION: | 6060 case CKM_MD5_KEY_DERIVATION: |
5891 if (keySize == 0) keySize = MD5_LENGTH; | 6061 if (keySize == 0) keySize = MD5_LENGTH; |
5892 if (keySize > MD5_LENGTH) { | 6062 if (keySize > MD5_LENGTH) { |
5893 crv = CKR_TEMPLATE_INCONSISTENT; | 6063 crv = CKR_TEMPLATE_INCONSISTENT; |
5894 break; | 6064 break; |
5895 } | 6065 } |
5896 » /* now allocate the hash contexts */ | 6066 » MD5_HashBuf(key_block,(const unsigned char*)att->attrib.pValue, |
5897 » md5 = MD5_NewContext(); | |
5898 » if (md5 == NULL) { | |
5899 » crv = CKR_HOST_MEMORY; | |
5900 » break; | |
5901 » } | |
5902 » MD5_Begin(md5); | |
5903 » MD5_Update(md5,(const unsigned char*)att->attrib.pValue, | |
5904 att->attrib.ulValueLen); | 6067 att->attrib.ulValueLen); |
5905 MD5_End(md5,key_block,&outLen,MD5_LENGTH); | |
5906 MD5_DestroyContext(md5, PR_TRUE); | |
5907 | 6068 |
5908 crv = sftk_forceAttribute (key,CKA_VALUE,key_block,keySize); | 6069 crv = sftk_forceAttribute (key,CKA_VALUE,key_block,keySize); |
5909 break; | 6070 break; |
5910 case CKM_SHA1_KEY_DERIVATION: | 6071 case CKM_SHA1_KEY_DERIVATION: |
5911 if (keySize == 0) keySize = SHA1_LENGTH; | 6072 if (keySize == 0) keySize = SHA1_LENGTH; |
5912 if (keySize > SHA1_LENGTH) { | 6073 if (keySize > SHA1_LENGTH) { |
5913 crv = CKR_TEMPLATE_INCONSISTENT; | 6074 crv = CKR_TEMPLATE_INCONSISTENT; |
5914 break; | 6075 break; |
5915 } | 6076 } |
5916 » /* now allocate the hash contexts */ | 6077 » SHA1_HashBuf(key_block,(const unsigned char*)att->attrib.pValue, |
5917 » sha = SHA1_NewContext(); | 6078 » » att->attrib.ulValueLen); |
5918 » if (sha == NULL) { | 6079 |
5919 » crv = CKR_HOST_MEMORY; | 6080 » crv = sftk_forceAttribute(key,CKA_VALUE,key_block,keySize); |
| 6081 » break; |
| 6082 |
| 6083 case CKM_SHA224_KEY_DERIVATION: |
| 6084 » if (keySize == 0) keySize = SHA224_LENGTH; |
| 6085 » if (keySize > SHA224_LENGTH) { |
| 6086 » crv = CKR_TEMPLATE_INCONSISTENT; |
5920 break; | 6087 break; |
5921 } | 6088 } |
5922 » SHA1_Begin(sha); | 6089 » SHA224_HashBuf(key_block,(const unsigned char*)att->attrib.pValue, |
5923 » SHA1_Update(sha,(const unsigned char*)att->attrib.pValue, | |
5924 att->attrib.ulValueLen); | 6090 att->attrib.ulValueLen); |
5925 » SHA1_End(sha,key_block,&outLen,SHA1_LENGTH); | 6091 |
5926 » SHA1_DestroyContext(sha, PR_TRUE); | 6092 » crv = sftk_forceAttribute(key,CKA_VALUE,key_block,keySize); |
| 6093 » break; |
| 6094 |
| 6095 case CKM_SHA256_KEY_DERIVATION: |
| 6096 » if (keySize == 0) keySize = SHA256_LENGTH; |
| 6097 » if (keySize > SHA256_LENGTH) { |
| 6098 » crv = CKR_TEMPLATE_INCONSISTENT; |
| 6099 » break; |
| 6100 » } |
| 6101 » SHA256_HashBuf(key_block,(const unsigned char*)att->attrib.pValue, |
| 6102 » » att->attrib.ulValueLen); |
| 6103 |
| 6104 » crv = sftk_forceAttribute(key,CKA_VALUE,key_block,keySize); |
| 6105 » break; |
| 6106 |
| 6107 case CKM_SHA384_KEY_DERIVATION: |
| 6108 » if (keySize == 0) keySize = SHA384_LENGTH; |
| 6109 » if (keySize > SHA384_LENGTH) { |
| 6110 » crv = CKR_TEMPLATE_INCONSISTENT; |
| 6111 » break; |
| 6112 » } |
| 6113 » SHA384_HashBuf(key_block,(const unsigned char*)att->attrib.pValue, |
| 6114 » » att->attrib.ulValueLen); |
| 6115 |
| 6116 » crv = sftk_forceAttribute(key,CKA_VALUE,key_block,keySize); |
| 6117 » break; |
| 6118 |
| 6119 case CKM_SHA512_KEY_DERIVATION: |
| 6120 » if (keySize == 0) keySize = SHA512_LENGTH; |
| 6121 » if (keySize > SHA512_LENGTH) { |
| 6122 » crv = CKR_TEMPLATE_INCONSISTENT; |
| 6123 » break; |
| 6124 » } |
| 6125 » SHA512_HashBuf(key_block,(const unsigned char*)att->attrib.pValue, |
| 6126 » » att->attrib.ulValueLen); |
5927 | 6127 |
5928 crv = sftk_forceAttribute(key,CKA_VALUE,key_block,keySize); | 6128 crv = sftk_forceAttribute(key,CKA_VALUE,key_block,keySize); |
5929 break; | 6129 break; |
5930 | 6130 |
5931 case CKM_DH_PKCS_DERIVE: | 6131 case CKM_DH_PKCS_DERIVE: |
5932 { | 6132 { |
5933 SECItem derived, dhPublic; | 6133 SECItem derived, dhPublic; |
5934 SECItem dhPrime, dhValue; | 6134 SECItem dhPrime, dhValue; |
5935 /* sourceKey - values for the local existing low key */ | 6135 /* sourceKey - values for the local existing low key */ |
5936 /* get prime and value attributes */ | 6136 /* get prime and value attributes */ |
(...skipping 23 matching lines...) Expand all Loading... |
5960 break; | 6160 break; |
5961 } | 6161 } |
5962 | 6162 |
5963 #ifdef NSS_ENABLE_ECC | 6163 #ifdef NSS_ENABLE_ECC |
5964 case CKM_ECDH1_DERIVE: | 6164 case CKM_ECDH1_DERIVE: |
5965 case CKM_ECDH1_COFACTOR_DERIVE: | 6165 case CKM_ECDH1_COFACTOR_DERIVE: |
5966 { | 6166 { |
5967 SECItem ecScalar, ecPoint; | 6167 SECItem ecScalar, ecPoint; |
5968 SECItem tmp; | 6168 SECItem tmp; |
5969 PRBool withCofactor = PR_FALSE; | 6169 PRBool withCofactor = PR_FALSE; |
5970 unsigned char secret_hash[20]; | |
5971 unsigned char *secret; | 6170 unsigned char *secret; |
5972 unsigned char *keyData = NULL; | 6171 unsigned char *keyData = NULL; |
5973 int secretlen, curveLen, pubKeyLen; | 6172 int secretlen, curveLen, pubKeyLen; |
5974 CK_ECDH1_DERIVE_PARAMS *mechParams; | 6173 CK_ECDH1_DERIVE_PARAMS *mechParams; |
5975 NSSLOWKEYPrivateKey *privKey; | 6174 NSSLOWKEYPrivateKey *privKey; |
5976 PLArenaPool *arena = NULL; | 6175 PLArenaPool *arena = NULL; |
5977 | 6176 |
5978 /* Check mechanism parameters */ | 6177 /* Check mechanism parameters */ |
5979 mechParams = (CK_ECDH1_DERIVE_PARAMS *) pMechanism->pParameter; | 6178 mechParams = (CK_ECDH1_DERIVE_PARAMS *) pMechanism->pParameter; |
5980 if ((pMechanism->ulParameterLen != sizeof(CK_ECDH1_DERIVE_PARAMS)) || | 6179 if ((pMechanism->ulParameterLen != sizeof(CK_ECDH1_DERIVE_PARAMS)) || |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6046 if (arena) { | 6245 if (arena) { |
6047 PORT_FreeArena(arena,PR_FALSE); | 6246 PORT_FreeArena(arena,PR_FALSE); |
6048 arena=NULL; | 6247 arena=NULL; |
6049 } | 6248 } |
6050 | 6249 |
6051 if (rv != SECSuccess) { | 6250 if (rv != SECSuccess) { |
6052 crv = sftk_MapCryptError(PORT_GetError()); | 6251 crv = sftk_MapCryptError(PORT_GetError()); |
6053 break; | 6252 break; |
6054 } | 6253 } |
6055 | 6254 |
6056 /* | |
6057 * tmp is the raw data created by ECDH_Derive, | |
6058 * secret and secretlen are the values we will eventually pass as our | |
6059 * generated key. | |
6060 */ | |
6061 secret = tmp.data; | |
6062 secretlen = tmp.len; | |
6063 | 6255 |
6064 /* | 6256 /* |
6065 * apply the kdf function. | 6257 * apply the kdf function. |
6066 */ | 6258 */ |
6067 » if (mechParams->kdf == CKD_SHA1_KDF) { | 6259 » if (mechParams->kdf == CKD_NULL) { |
6068 » /* Compute SHA1 hash */ | 6260 » /* |
6069 » PORT_Memset(secret_hash, 0, 20); | 6261 » * tmp is the raw data created by ECDH_Derive, |
6070 » rv = SHA1_HashBuf(secret_hash, tmp.data, tmp.len); | 6262 » * secret and secretlen are the values we will |
| 6263 » * eventually pass as our generated key. |
| 6264 » */ |
| 6265 » secret = tmp.data; |
| 6266 » secretlen = tmp.len; |
| 6267 » } else { |
| 6268 » secretlen = keySize; |
| 6269 » rv = sftk_ANSI_X9_63_kdf(&secret, keySize, |
| 6270 » » » &tmp, mechParams->pSharedData, |
| 6271 » » » mechParams->ulSharedDataLen, mechParams->kdf); |
| 6272 » PORT_ZFree(tmp.data, tmp.len); |
6071 if (rv != SECSuccess) { | 6273 if (rv != SECSuccess) { |
6072 PORT_ZFree(tmp.data, tmp.len); | |
6073 crv = CKR_HOST_MEMORY; | 6274 crv = CKR_HOST_MEMORY; |
6074 break; | 6275 break; |
6075 » } | 6276 » } |
6076 » secret = secret_hash; | 6277 » tmp.data = secret; |
6077 » secretlen = 20; | 6278 » tmp.len = secretlen; |
6078 } | 6279 } |
6079 | 6280 |
6080 /* | 6281 /* |
6081 * if keySize is supplied, then we are generating a key of a specific | 6282 * if keySize is supplied, then we are generating a key of a specific |
6082 * length. This is done by taking the least significant 'keySize' | 6283 * length. This is done by taking the least significant 'keySize' |
6083 * bytes from the unsigned value calculated by ECDH. Note: this may | 6284 * bytes from the unsigned value calculated by ECDH. Note: this may |
6084 * mean padding temp with extra leading zeros from what ECDH_Derive | 6285 * mean padding temp with extra leading zeros from what ECDH_Derive |
6085 * already returned (which itself may contain leading zeros). | 6286 * already returned (which itself may contain leading zeros). |
6086 */ | 6287 */ |
6087 if (keySize) { | 6288 if (keySize) { |
(...skipping 10 matching lines...) Expand all Loading... |
6098 secret += (secretlen - keySize); | 6299 secret += (secretlen - keySize); |
6099 } | 6300 } |
6100 secretlen = keySize; | 6301 secretlen = keySize; |
6101 } | 6302 } |
6102 | 6303 |
6103 sftk_forceAttribute(key, CKA_VALUE, secret, secretlen); | 6304 sftk_forceAttribute(key, CKA_VALUE, secret, secretlen); |
6104 PORT_ZFree(tmp.data, tmp.len); | 6305 PORT_ZFree(tmp.data, tmp.len); |
6105 if (keyData) { | 6306 if (keyData) { |
6106 PORT_ZFree(keyData, keySize); | 6307 PORT_ZFree(keyData, keySize); |
6107 } | 6308 } |
6108 PORT_Memset(secret_hash, 0, 20); | |
6109 | |
6110 break; | 6309 break; |
6111 | 6310 |
6112 ec_loser: | 6311 ec_loser: |
6113 crv = CKR_ARGUMENTS_BAD; | 6312 crv = CKR_ARGUMENTS_BAD; |
6114 PORT_Free(ecScalar.data); | 6313 PORT_Free(ecScalar.data); |
6115 if (privKey != sourceKey->objectInfo) | 6314 if (privKey != sourceKey->objectInfo) |
6116 nsslowkey_DestroyPrivateKey(privKey); | 6315 nsslowkey_DestroyPrivateKey(privKey); |
6117 if (arena) { | 6316 if (arena) { |
6118 PORT_FreeArena(arena, PR_FALSE); | 6317 PORT_FreeArena(arena, PR_FALSE); |
6119 } | 6318 } |
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6532 att = sftk_FindAttribute(key,CKA_VALUE); | 6731 att = sftk_FindAttribute(key,CKA_VALUE); |
6533 sftk_FreeObject(key); | 6732 sftk_FreeObject(key); |
6534 if (!att) { | 6733 if (!att) { |
6535 return CKR_KEY_HANDLE_INVALID; | 6734 return CKR_KEY_HANDLE_INVALID; |
6536 } | 6735 } |
6537 crv = NSC_DigestUpdate(hSession,(CK_BYTE_PTR)att->attrib.pValue, | 6736 crv = NSC_DigestUpdate(hSession,(CK_BYTE_PTR)att->attrib.pValue, |
6538 att->attrib.ulValueLen); | 6737 att->attrib.ulValueLen); |
6539 sftk_FreeAttribute(att); | 6738 sftk_FreeAttribute(att); |
6540 return crv; | 6739 return crv; |
6541 } | 6740 } |
OLD | NEW |