Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(327)

Side by Side Diff: mozilla/security/nss/lib/pk11wrap/pk11skey.c

Issue 10961060: Update NSS to NSS 3.14 Beta 1. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/deps/third_party/nss/
Patch Set: Add the NSS snapshot timestamp to README.chromium and nss-checkout.sh Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 the Symkey wrapper and the PKCS context 5 * This file implements the Symkey wrapper and the PKCS context
6 * Interfaces. 6 * Interfaces.
7 */ 7 */
8 8
9 #include "seccomon.h" 9 #include "seccomon.h"
10 #include "secmod.h" 10 #include "secmod.h"
(...skipping 795 matching lines...) Expand 10 before | Expand all | Expand 10 after
806 } 806 }
807 807
808 PK11SymKey * 808 PK11SymKey *
809 pk11_CopyToSlot(PK11SlotInfo *slot,CK_MECHANISM_TYPE type, 809 pk11_CopyToSlot(PK11SlotInfo *slot,CK_MECHANISM_TYPE type,
810 CK_ATTRIBUTE_TYPE operation, PK11SymKey *symKey) 810 CK_ATTRIBUTE_TYPE operation, PK11SymKey *symKey)
811 { 811 {
812 return pk11_CopyToSlotPerm(slot, type, operation, 0, PR_FALSE, symKey); 812 return pk11_CopyToSlotPerm(slot, type, operation, 0, PR_FALSE, symKey);
813 } 813 }
814 814
815 /* 815 /*
816 * Make sure the slot we are in the correct slot for the operation 816 * Make sure the slot we are in is the correct slot for the operation
817 * by verifying that it supports all of the specified mechanism types.
818 */
819 PK11SymKey *
820 pk11_ForceSlotMultiple(PK11SymKey *symKey, CK_MECHANISM_TYPE *type,
821 » » » int mechCount, CK_ATTRIBUTE_TYPE operation)
822 {
823 PK11SlotInfo *slot = symKey->slot;
824 PK11SymKey *newKey = NULL;
825 PRBool needToCopy = PR_FALSE;
826 int i;
827
828 if (slot == NULL) {
829 » needToCopy = PR_TRUE;
830 } else {
831 » i = 0;
832 » while ((i < mechCount) && (needToCopy == PR_FALSE)) {
833 » if (!PK11_DoesMechanism(slot,type[i])) {
834 » » needToCopy = PR_TRUE;
835 » }
836 » i++;
837 » }
838 }
839
840 if (needToCopy == PR_TRUE) {
841 » slot = PK11_GetBestSlotMultiple(type,mechCount,symKey->cx);
842 » if (slot == NULL) {
843 » PORT_SetError( SEC_ERROR_NO_MODULE );
844 » return NULL;
845 » }
846 » newKey = pk11_CopyToSlot(slot, type[0], operation, symKey);
847 » PK11_FreeSlot(slot);
848 }
849 return newKey;
850 }
851
852 /*
853 * Make sure the slot we are in is the correct slot for the operation
817 */ 854 */
818 PK11SymKey * 855 PK11SymKey *
819 pk11_ForceSlot(PK11SymKey *symKey,CK_MECHANISM_TYPE type, 856 pk11_ForceSlot(PK11SymKey *symKey,CK_MECHANISM_TYPE type,
820 CK_ATTRIBUTE_TYPE operation) 857 CK_ATTRIBUTE_TYPE operation)
821 { 858 {
822 PK11SlotInfo *slot = symKey->slot; 859 return pk11_ForceSlotMultiple(symKey, &type, 1, operation);
823 PK11SymKey *newKey = NULL;
824
825 if ((slot== NULL) || !PK11_DoesMechanism(slot,type)) {
826 » slot = PK11_GetBestSlot(type,symKey->cx);
827 » if (slot == NULL) {
828 » PORT_SetError( SEC_ERROR_NO_MODULE );
829 » return NULL;
830 » }
831 » newKey = pk11_CopyToSlot(slot, type, operation, symKey);
832 » PK11_FreeSlot(slot);
833 }
834 return newKey;
835 } 860 }
836 861
837 PK11SymKey * 862 PK11SymKey *
838 PK11_MoveSymKey(PK11SlotInfo *slot, CK_ATTRIBUTE_TYPE operation, 863 PK11_MoveSymKey(PK11SlotInfo *slot, CK_ATTRIBUTE_TYPE operation,
839 CK_FLAGS flags, PRBool perm, PK11SymKey *symKey) 864 CK_FLAGS flags, PRBool perm, PK11SymKey *symKey)
840 { 865 {
841 if (symKey->slot == slot) { 866 if (symKey->slot == slot) {
842 if (perm) { 867 if (perm) {
843 return PK11_ConvertSessionSymKeyToTokenSymKey(symKey,symKey->cx); 868 return PK11_ConvertSessionSymKeyToTokenSymKey(symKey,symKey->cx);
844 } else { 869 } else {
(...skipping 677 matching lines...) Expand 10 before | Expand all | Expand 10 after
1522 } 1547 }
1523 if (newBaseKey) 1548 if (newBaseKey)
1524 PK11_FreeSymKey(newBaseKey); 1549 PK11_FreeSymKey(newBaseKey);
1525 if (crv != CKR_OK) { 1550 if (crv != CKR_OK) {
1526 PK11_FreeSymKey(symKey); 1551 PK11_FreeSymKey(symKey);
1527 return NULL; 1552 return NULL;
1528 } 1553 }
1529 return symKey; 1554 return symKey;
1530 } 1555 }
1531 1556
1557 /* Create a new key by concatenating base and data
1558 */
1559 static PK11SymKey *pk11_ConcatenateBaseAndData(PK11SymKey *base,
1560 CK_BYTE *data, CK_ULONG dataLen, CK_MECHANISM_TYPE target,
1561 CK_ATTRIBUTE_TYPE operation)
1562 {
1563 CK_KEY_DERIVATION_STRING_DATA mechParams;
1564 SECItem param;
1565
1566 if (base == NULL) {
1567 PORT_SetError( SEC_ERROR_INVALID_ARGS );
1568 return NULL;
1569 }
1570
1571 mechParams.pData = data;
1572 mechParams.ulLen = dataLen;
1573 param.data = (unsigned char *)&mechParams;
1574 param.len = sizeof(CK_KEY_DERIVATION_STRING_DATA);
1575
1576 return PK11_Derive(base, CKM_CONCATENATE_BASE_AND_DATA,
1577 &param, target, operation, 0);
1578 }
1579
1580 /* Create a new key by concatenating base and key
1581 */
1582 static PK11SymKey *pk11_ConcatenateBaseAndKey(PK11SymKey *base,
1583 PK11SymKey *key, CK_MECHANISM_TYPE target,
1584 CK_ATTRIBUTE_TYPE operation, CK_ULONG keySize)
1585 {
1586 SECItem param;
1587
1588 if ((base == NULL) || (key == NULL)) {
1589 PORT_SetError( SEC_ERROR_INVALID_ARGS );
1590 return NULL;
1591 }
1592
1593 param.data = (unsigned char *)&(key->objectID);
1594 param.len = sizeof(CK_OBJECT_HANDLE);
1595
1596 return PK11_Derive(base, CKM_CONCATENATE_BASE_AND_KEY,
1597 &param, target, operation, keySize);
1598 }
1599
1600 /* Create a new key whose value is the hash of tobehashed.
1601 * type is the mechanism for the derived key.
1602 */
1603 static PK11SymKey *pk11_HashKeyDerivation(PK11SymKey *toBeHashed,
1604 CK_MECHANISM_TYPE hashMechanism, CK_MECHANISM_TYPE target,
1605 CK_ATTRIBUTE_TYPE operation, CK_ULONG keySize)
1606 {
1607 return PK11_Derive(toBeHashed, hashMechanism, NULL, target, operation, keySi ze);
1608 }
1609
1610 /* This function implements the ANSI X9.63 key derivation function
1611 */
1612 static PK11SymKey *pk11_ANSIX963Derive(PK11SymKey *sharedSecret,
1613 CK_EC_KDF_TYPE kdf, SECItem *sharedData,
1614 CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation,
1615 CK_ULONG keySize)
1616 {
1617 CK_KEY_TYPE keyType;
1618 CK_MECHANISM_TYPE hashMechanism, mechanismArray[4];
1619 CK_ULONG derivedKeySize, HashLen, counter, maxCounter, bufferLen;
1620 CK_ULONG SharedInfoLen;
1621 CK_BYTE *buffer = NULL;
1622 PK11SymKey *toBeHashed, *hashOutput;
1623 PK11SymKey *newSharedSecret = NULL;
1624 PK11SymKey *oldIntermediateResult, *intermediateResult = NULL;
1625
1626 if (sharedSecret == NULL) {
1627 PORT_SetError( SEC_ERROR_INVALID_ARGS );
1628 return NULL;
1629 }
1630
1631 switch (kdf) {
1632 case CKD_SHA1_KDF:
1633 HashLen = SHA1_LENGTH;
1634 hashMechanism = CKM_SHA1_KEY_DERIVATION;
1635 break;
1636 case CKD_SHA224_KDF:
1637 HashLen = SHA224_LENGTH;
1638 hashMechanism = CKM_SHA224_KEY_DERIVATION;
1639 break;
1640 case CKD_SHA256_KDF:
1641 HashLen = SHA256_LENGTH;
1642 hashMechanism = CKM_SHA256_KEY_DERIVATION;
1643 break;
1644 case CKD_SHA384_KDF:
1645 HashLen = SHA384_LENGTH;
1646 hashMechanism = CKM_SHA384_KEY_DERIVATION;
1647 break;
1648 case CKD_SHA512_KDF:
1649 HashLen = SHA512_LENGTH;
1650 hashMechanism = CKM_SHA512_KEY_DERIVATION;
1651 break;
1652 default:
1653 PORT_SetError( SEC_ERROR_INVALID_ARGS );
1654 return NULL;
1655 }
1656
1657 derivedKeySize = keySize;
1658 if (derivedKeySize == 0) {
1659 keyType = PK11_GetKeyType(target,keySize);
1660 derivedKeySize = pk11_GetPredefinedKeyLength(keyType);
1661 if (derivedKeySize == 0) {
1662 derivedKeySize = HashLen;
1663 }
1664 }
1665
1666 /* Check that key_len isn't too long. The maximum key length could be
1667 * greatly increased if the code below did not limit the 4-byte counter
1668 * to a maximum value of 255. */
1669 if (derivedKeySize > 254 * HashLen) {
1670 PORT_SetError( SEC_ERROR_INVALID_ARGS );
1671 return NULL;
1672 }
1673
1674 maxCounter = derivedKeySize / HashLen;
1675 if (derivedKeySize > maxCounter * HashLen)
1676 maxCounter++;
1677
1678 if ((sharedData == NULL) || (sharedData->data == NULL))
1679 SharedInfoLen = 0;
1680 else
1681 SharedInfoLen = sharedData->len;
1682
1683 bufferLen = SharedInfoLen + 4;
1684
1685 /* Populate buffer with Counter || sharedData
1686 * where Counter is 0x00000001. */
1687 buffer = (unsigned char *)PORT_Alloc(bufferLen);
1688 if (buffer == NULL) {
1689 PORT_SetError(SEC_ERROR_NO_MEMORY);
1690 return NULL;
1691 }
1692
1693 buffer[0] = 0;
1694 buffer[1] = 0;
1695 buffer[2] = 0;
1696 buffer[3] = 1;
1697 if (SharedInfoLen > 0) {
1698 PORT_Memcpy(&buffer[4], sharedData->data, SharedInfoLen);
1699 }
1700
1701 /* Look for a slot that supports the mechanisms needed
1702 * to implement the ANSI X9.63 KDF as well as the
1703 * target mechanism.
1704 */
1705 mechanismArray[0] = CKM_CONCATENATE_BASE_AND_DATA;
1706 mechanismArray[1] = hashMechanism;
1707 mechanismArray[2] = CKM_CONCATENATE_BASE_AND_KEY;
1708 mechanismArray[3] = target;
1709
1710 newSharedSecret = pk11_ForceSlotMultiple(sharedSecret,
1711 mechanismArray, 4, operation);
1712 if (newSharedSecret != NULL) {
1713 sharedSecret = newSharedSecret;
1714 }
1715
1716 for(counter=1; counter <= maxCounter; counter++) {
1717 /* Concatenate shared_secret and buffer */
1718 toBeHashed = pk11_ConcatenateBaseAndData(sharedSecret, buffer,
1719 bufferLen, hashMechanism, operation);
1720 if (toBeHashed == NULL) {
1721 goto loser;
1722 }
1723
1724 /* Hash value */
1725 if (maxCounter == 1) {
1726 /* In this case the length of the key to be derived is
1727 * less than or equal to the length of the hash output.
1728 * So, the output of the hash operation will be the
1729 * dervied key. */
1730 hashOutput = pk11_HashKeyDerivation(toBeHashed, hashMechanism,
1731 target, operation, keySize);
1732 } else {
1733 /* In this case, the output of the hash operation will be
1734 * concatenated with other data to create the derived key. */
1735 hashOutput = pk11_HashKeyDerivation(toBeHashed, hashMechanism,
1736 CKM_CONCATENATE_BASE_AND_KEY, operation, 0);
1737 }
1738 PK11_FreeSymKey(toBeHashed);
1739 if (hashOutput == NULL) {
1740 goto loser;
1741 }
1742
1743 /* Append result to intermediate result, if necessary */
1744 oldIntermediateResult = intermediateResult;
1745
1746 if (oldIntermediateResult == NULL) {
1747 intermediateResult = hashOutput;
1748 } else {
1749 if (counter == maxCounter) {
1750 /* This is the final concatenation, and so the output
1751 * will be the derived key. */
1752 intermediateResult =
1753 pk11_ConcatenateBaseAndKey(oldIntermediateResult,
1754 hashOutput, target, operation, keySize);
1755 } else {
1756 /* The output of this concatenation will be concatenated
1757 * with other data to create the derived key. */
1758 intermediateResult =
1759 pk11_ConcatenateBaseAndKey(oldIntermediateResult,
1760 hashOutput, CKM_CONCATENATE_BASE_AND_KEY,
1761 operation, 0);
1762 }
1763
1764 PK11_FreeSymKey(hashOutput);
1765 PK11_FreeSymKey(oldIntermediateResult);
1766 if (intermediateResult == NULL) {
1767 goto loser;
1768 }
1769 }
1770
1771 /* Increment counter (assumes maxCounter < 255) */
1772 buffer[3]++;
1773 }
1774
1775 PORT_ZFree(buffer, bufferLen);
1776 if (newSharedSecret != NULL)
1777 PK11_FreeSymKey(newSharedSecret);
1778 return intermediateResult;
1779
1780 loser:
1781 if (buffer != NULL)
1782 PORT_ZFree(buffer, bufferLen);
1783 if (newSharedSecret != NULL)
1784 PK11_FreeSymKey(newSharedSecret);
1785 if (intermediateResult != NULL)
1786 PK11_FreeSymKey(intermediateResult);
1787 return NULL;
1788 }
1789
1532 /* 1790 /*
1533 * This Generates a wrapping key based on a privateKey, publicKey, and two 1791 * This Generates a wrapping key based on a privateKey, publicKey, and two
1534 * random numbers. For Mail usage RandomB should be NULL. In the Sender's 1792 * random numbers. For Mail usage RandomB should be NULL. In the Sender's
1535 * case RandomA is generate, outherwize it is passed. 1793 * case RandomA is generate, outherwize it is passed.
1536 */ 1794 */
1537 static unsigned char *rb_email = NULL; 1795 static unsigned char *rb_email = NULL;
1538 1796
1539 PK11SymKey * 1797 PK11SymKey *
1540 PK11_PubDerive(SECKEYPrivateKey *privKey, SECKEYPublicKey *pubKey, 1798 PK11_PubDerive(SECKEYPrivateKey *privKey, SECKEYPublicKey *pubKey,
1541 PRBool isSender, SECItem *randomA, SECItem *randomB, 1799 PRBool isSender, SECItem *randomA, SECItem *randomB,
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
1670 attrs++; 1928 attrs++;
1671 PK11_SETATTRS(attrs, operation, &cktrue, 1); attrs++; 1929 PK11_SETATTRS(attrs, operation, &cktrue, 1); attrs++;
1672 PK11_SETATTRS(attrs, CKA_VALUE_LEN, &key_size, sizeof(key_size)); 1930 PK11_SETATTRS(attrs, CKA_VALUE_LEN, &key_size, sizeof(key_size));
1673 attrs++; 1931 attrs++;
1674 templateCount = attrs - keyTemplate; 1932 templateCount = attrs - keyTemplate;
1675 PR_ASSERT(templateCount <= sizeof(keyTemplate)/sizeof(CK_ATTRIBUTE)) ; 1933 PR_ASSERT(templateCount <= sizeof(keyTemplate)/sizeof(CK_ATTRIBUTE)) ;
1676 1934
1677 keyType = PK11_GetKeyType(target,keySize); 1935 keyType = PK11_GetKeyType(target,keySize);
1678 key_size = keySize; 1936 key_size = keySize;
1679 if (key_size == 0) { 1937 if (key_size == 0) {
1680 » » if (pk11_GetPredefinedKeyLength(keyType)) { 1938 » » if ((key_size = pk11_GetPredefinedKeyLength(keyType))) {
1681 templateCount --; 1939 templateCount --;
1682 } else { 1940 } else {
1683 /* sigh, some tokens can't figure this out and require 1941 /* sigh, some tokens can't figure this out and require
1684 * CKA_VALUE_LEN to be set */ 1942 * CKA_VALUE_LEN to be set */
1685 key_size = SHA1_LENGTH; 1943 key_size = SHA1_LENGTH;
1686 } 1944 }
1687 } 1945 }
1688 symKey->size = key_size; 1946 symKey->size = key_size;
1689 1947
1690 mechParams = PORT_ZNew(CK_ECDH1_DERIVE_PARAMS); 1948 mechParams = PORT_ZNew(CK_ECDH1_DERIVE_PARAMS);
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1730 1988
1731 if (crv == CKR_OK) return symKey; 1989 if (crv == CKR_OK) return symKey;
1732 PORT_SetError( PK11_MapError(crv) ); 1990 PORT_SetError( PK11_MapError(crv) );
1733 } 1991 }
1734 } 1992 }
1735 1993
1736 PK11_FreeSymKey(symKey); 1994 PK11_FreeSymKey(symKey);
1737 return NULL; 1995 return NULL;
1738 } 1996 }
1739 1997
1998 /* Returns the size of the public key, or 0 if there
1999 * is an error. */
2000 static CK_ULONG
2001 pk11_ECPubKeySize(SECItem *publicValue)
2002 {
2003 if (publicValue->data[0] == 0x04) {
2004 /* key encoded in uncompressed form */
2005 return((publicValue->len - 1)/2);
2006 } else if ( (publicValue->data[0] == 0x02) ||
2007 (publicValue->data[0] == 0x03)) {
2008 /* key encoded in compressed form */
2009 return(publicValue->len - 1);
2010 }
2011 /* key encoding not recognized */
2012 return(0);
2013 }
2014
1740 static PK11SymKey * 2015 static PK11SymKey *
1741 pk11_PubDeriveECKeyWithKDF( 2016 pk11_PubDeriveECKeyWithKDF(
1742 SECKEYPrivateKey *privKey, SECKEYPublicKey *pubKey, 2017 SECKEYPrivateKey *privKey, SECKEYPublicKey *pubKey,
1743 PRBool isSender, SECItem *randomA, SECItem *randomB, 2018 PRBool isSender, SECItem *randomA, SECItem *randomB,
1744 CK_MECHANISM_TYPE derive, CK_MECHANISM_TYPE target, 2019 CK_MECHANISM_TYPE derive, CK_MECHANISM_TYPE target,
1745 CK_ATTRIBUTE_TYPE operation, int keySize, 2020 CK_ATTRIBUTE_TYPE operation, int keySize,
1746 CK_ULONG kdf, SECItem *sharedData, void *wincx) 2021 CK_ULONG kdf, SECItem *sharedData, void *wincx)
1747 { 2022 {
1748 PK11SlotInfo *slot = privKey->pkcs11Slot; 2023 PK11SlotInfo *slot = privKey->pkcs11Slot;
1749 PK11SymKey *symKey; 2024 PK11SymKey *symKey;
2025 PK11SymKey *SharedSecret;
1750 CK_MECHANISM mechanism; 2026 CK_MECHANISM mechanism;
1751 CK_RV crv; 2027 CK_RV crv;
1752 CK_BBOOL cktrue = CK_TRUE; 2028 CK_BBOOL cktrue = CK_TRUE;
1753 CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY; 2029 CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY;
1754 CK_KEY_TYPE keyType = CKK_GENERIC_SECRET; 2030 CK_KEY_TYPE keyType = CKK_GENERIC_SECRET;
1755 CK_ULONG key_size = 0; 2031 CK_ULONG key_size = 0;
1756 CK_ATTRIBUTE keyTemplate[4]; 2032 CK_ATTRIBUTE keyTemplate[4];
1757 int templateCount; 2033 int templateCount;
1758 CK_ATTRIBUTE *attrs = keyTemplate; 2034 CK_ATTRIBUTE *attrs = keyTemplate;
1759 CK_ECDH1_DERIVE_PARAMS *mechParams = NULL; 2035 CK_ECDH1_DERIVE_PARAMS *mechParams = NULL;
1760 2036
1761 if (pubKey->keyType != ecKey) { 2037 if (pubKey->keyType != ecKey) {
1762 PORT_SetError(SEC_ERROR_BAD_KEY); 2038 PORT_SetError(SEC_ERROR_BAD_KEY);
1763 return NULL; 2039 return NULL;
1764 } 2040 }
1765 if ((kdf < CKD_NULL) || (kdf > CKD_SHA1_KDF)) { 2041 if ((kdf != CKD_NULL) && (kdf != CKD_SHA1_KDF) &&
2042 » (kdf != CKD_SHA224_KDF) && (kdf != CKD_SHA256_KDF) &&
2043 » (kdf != CKD_SHA384_KDF) && (kdf != CKD_SHA512_KDF)) {
1766 PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); 2044 PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
1767 return NULL; 2045 return NULL;
1768 } 2046 }
1769 2047
1770 /* get our key Structure */ 2048 /* get our key Structure */
1771 symKey = pk11_CreateSymKey(slot, target, PR_TRUE, PR_TRUE, wincx); 2049 symKey = pk11_CreateSymKey(slot, target, PR_TRUE, PR_TRUE, wincx);
1772 if (symKey == NULL) { 2050 if (symKey == NULL) {
1773 return NULL; 2051 return NULL;
1774 } 2052 }
1775 2053
1776 symKey->origin = PK11_OriginDerive; 2054 symKey->origin = PK11_OriginDerive;
1777 2055
1778 PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, sizeof(keyClass)); attrs++; 2056 PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, sizeof(keyClass)); attrs++;
1779 PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType)); attrs++; 2057 PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType)); attrs++;
1780 PK11_SETATTRS(attrs, operation, &cktrue, 1); attrs++; 2058 PK11_SETATTRS(attrs, operation, &cktrue, 1); attrs++;
1781 PK11_SETATTRS(attrs, CKA_VALUE_LEN, &key_size, sizeof(key_size)); attrs++; 2059 PK11_SETATTRS(attrs, CKA_VALUE_LEN, &key_size, sizeof(key_size)); attrs++;
1782 templateCount = attrs - keyTemplate; 2060 templateCount = attrs - keyTemplate;
1783 PR_ASSERT(templateCount <= sizeof(keyTemplate)/sizeof(CK_ATTRIBUTE)); 2061 PR_ASSERT(templateCount <= sizeof(keyTemplate)/sizeof(CK_ATTRIBUTE));
1784 2062
1785 keyType = PK11_GetKeyType(target,keySize); 2063 keyType = PK11_GetKeyType(target,keySize);
1786 key_size = keySize; 2064 key_size = keySize;
1787 if (key_size == 0) { 2065 if (key_size == 0) {
1788 » if (pk11_GetPredefinedKeyLength(keyType)) { 2066 » if ((key_size = pk11_GetPredefinedKeyLength(keyType))) {
1789 templateCount --; 2067 templateCount --;
1790 } else { 2068 } else {
1791 /* sigh, some tokens can't figure this out and require 2069 /* sigh, some tokens can't figure this out and require
1792 * CKA_VALUE_LEN to be set */ 2070 * CKA_VALUE_LEN to be set */
1793 switch (kdf) { 2071 switch (kdf) {
1794 case CKD_NULL: 2072 case CKD_NULL:
1795 » » key_size = (pubKey->u.ec.publicValue.len-1)/2; 2073 » » key_size = pk11_ECPubKeySize(&pubKey->u.ec.publicValue);
2074 » » if (key_size == 0) {
2075 » » PK11_FreeSymKey(symKey);
2076 » » return NULL;
2077 » » }
1796 break; 2078 break;
1797 case CKD_SHA1_KDF: 2079 case CKD_SHA1_KDF:
1798 key_size = SHA1_LENGTH; 2080 key_size = SHA1_LENGTH;
1799 break; 2081 break;
2082 case CKD_SHA224_KDF:
2083 key_size = SHA224_LENGTH;
2084 break;
2085 case CKD_SHA256_KDF:
2086 key_size = SHA256_LENGTH;
2087 break;
2088 case CKD_SHA384_KDF:
2089 key_size = SHA384_LENGTH;
2090 break;
2091 case CKD_SHA512_KDF:
2092 key_size = SHA512_LENGTH;
2093 break;
1800 default: 2094 default:
1801 PORT_Assert(!"Invalid CKD"); 2095 PORT_Assert(!"Invalid CKD");
1802 PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); 2096 PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
1803 return NULL; 2097 return NULL;
1804 } 2098 }
1805 } 2099 }
1806 } 2100 }
1807 symKey->size = key_size; 2101 symKey->size = key_size;
1808 2102
1809 mechParams = PORT_ZNew(CK_ECDH1_DERIVE_PARAMS); 2103 mechParams = PORT_ZNew(CK_ECDH1_DERIVE_PARAMS);
(...skipping 15 matching lines...) Expand all
1825 mechanism.mechanism = derive; 2119 mechanism.mechanism = derive;
1826 mechanism.pParameter = mechParams; 2120 mechanism.pParameter = mechParams;
1827 mechanism.ulParameterLen = sizeof(CK_ECDH1_DERIVE_PARAMS); 2121 mechanism.ulParameterLen = sizeof(CK_ECDH1_DERIVE_PARAMS);
1828 2122
1829 pk11_EnterKeyMonitor(symKey); 2123 pk11_EnterKeyMonitor(symKey);
1830 crv = PK11_GETTAB(slot)->C_DeriveKey(symKey->session, &mechanism, 2124 crv = PK11_GETTAB(slot)->C_DeriveKey(symKey->session, &mechanism,
1831 privKey->pkcs11ID, keyTemplate, templateCount, &symKey->objectID); 2125 privKey->pkcs11ID, keyTemplate, templateCount, &symKey->objectID);
1832 pk11_ExitKeyMonitor(symKey); 2126 pk11_ExitKeyMonitor(symKey);
1833 2127
1834 /* old PKCS #11 spec was ambiguous on what needed to be passed, 2128 /* old PKCS #11 spec was ambiguous on what needed to be passed,
1835 * try this again with and encoded public key */ 2129 * try this again with an encoded public key */
1836 if (crv != CKR_OK) { 2130 if (crv != CKR_OK) {
1837 SECItem *pubValue = SEC_ASN1EncodeItem(NULL, NULL, 2131 SECItem *pubValue = SEC_ASN1EncodeItem(NULL, NULL,
1838 &pubKey->u.ec.publicValue, 2132 &pubKey->u.ec.publicValue,
1839 SEC_ASN1_GET(SEC_OctetStringTemplate)); 2133 SEC_ASN1_GET(SEC_OctetStringTemplate));
1840 if (pubValue == NULL) { 2134 if (pubValue == NULL) {
1841 goto loser; 2135 goto loser;
1842 } 2136 }
1843 mechParams->ulPublicDataLen = pubValue->len; 2137 mechParams->ulPublicDataLen = pubValue->len;
1844 mechParams->pPublicData = pubValue->data; 2138 mechParams->pPublicData = pubValue->data;
1845 2139
1846 pk11_EnterKeyMonitor(symKey); 2140 pk11_EnterKeyMonitor(symKey);
1847 crv = PK11_GETTAB(slot)->C_DeriveKey(symKey->session, 2141 crv = PK11_GETTAB(slot)->C_DeriveKey(symKey->session,
1848 &mechanism, privKey->pkcs11ID, keyTemplate, 2142 &mechanism, privKey->pkcs11ID, keyTemplate,
1849 templateCount, &symKey->objectID); 2143 templateCount, &symKey->objectID);
1850 pk11_ExitKeyMonitor(symKey); 2144 pk11_ExitKeyMonitor(symKey);
1851 2145
2146 if ((crv != CKR_OK) && (kdf != CKD_NULL)) {
2147 /* Some PKCS #11 libraries cannot perform the key derivation
2148 * function. So, try calling C_DeriveKey with CKD_NULL and then
2149 * performing the KDF separately.
2150 */
2151 CK_ULONG derivedKeySize = key_size;
2152
2153 keyType = CKK_GENERIC_SECRET;
2154 key_size = pk11_ECPubKeySize(&pubKey->u.ec.publicValue);
2155 if (key_size == 0) {
2156 SECITEM_FreeItem(pubValue,PR_TRUE);
2157 goto loser;
2158 }
2159 SharedSecret = symKey;
2160 SharedSecret->size = key_size;
2161
2162 mechParams->kdf = CKD_NULL;
2163 mechParams->ulSharedDataLen = 0;
2164 mechParams->pSharedData = NULL;
2165 mechParams->ulPublicDataLen = pubKey->u.ec.publicValue.len;
2166 mechParams->pPublicData = pubKey->u.ec.publicValue.data;
2167
2168 pk11_EnterKeyMonitor(SharedSecret);
2169 crv = PK11_GETTAB(slot)->C_DeriveKey(SharedSecret->session,
2170 &mechanism, privKey->pkcs11ID, keyTemplate,
2171 templateCount, &SharedSecret->objectID);
2172 pk11_ExitKeyMonitor(SharedSecret);
2173
2174 if (crv != CKR_OK) {
2175 /* old PKCS #11 spec was ambiguous on what needed to be passed,
2176 * try this one final time with an encoded public key */
2177 mechParams->ulPublicDataLen = pubValue->len;
2178 mechParams->pPublicData = pubValue->data;
2179
2180 pk11_EnterKeyMonitor(SharedSecret);
2181 crv = PK11_GETTAB(slot)->C_DeriveKey(SharedSecret->session,
2182 &mechanism, privKey->pkcs11ID, keyTemplate,
2183 templateCount, &SharedSecret->objectID);
2184 pk11_ExitKeyMonitor(SharedSecret);
2185 }
2186
2187 /* Perform KDF. */
2188 if (crv == CKR_OK) {
2189 symKey = pk11_ANSIX963Derive(SharedSecret, kdf,
2190 sharedData, target, operation,
2191 derivedKeySize);
2192 PK11_FreeSymKey(SharedSecret);
2193 if (symKey == NULL) {
2194 SECITEM_FreeItem(pubValue,PR_TRUE);
2195 PORT_ZFree(mechParams, sizeof(CK_ECDH1_DERIVE_PARAMS));
2196 return NULL;
2197 }
2198 }
2199 }
1852 SECITEM_FreeItem(pubValue,PR_TRUE); 2200 SECITEM_FreeItem(pubValue,PR_TRUE);
1853 } 2201 }
1854 2202
1855 loser: 2203 loser:
1856 PORT_ZFree(mechParams, sizeof(CK_ECDH1_DERIVE_PARAMS)); 2204 PORT_ZFree(mechParams, sizeof(CK_ECDH1_DERIVE_PARAMS));
1857 2205
1858 if (crv != CKR_OK) { 2206 if (crv != CKR_OK) {
1859 PK11_FreeSymKey(symKey); 2207 PK11_FreeSymKey(symKey);
1860 symKey = NULL; 2208 symKey = NULL;
1861 PORT_SetError( PK11_MapError(crv) ); 2209 PORT_SetError( PK11_MapError(crv) );
(...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after
2314 PK11_ExitSlotMonitor(symKey->slot); 2662 PK11_ExitSlotMonitor(symKey->slot);
2315 return rv; 2663 return rv;
2316 } 2664 }
2317 2665
2318 CK_OBJECT_HANDLE 2666 CK_OBJECT_HANDLE
2319 PK11_GetSymKeyHandle(PK11SymKey *symKey) 2667 PK11_GetSymKeyHandle(PK11SymKey *symKey)
2320 { 2668 {
2321 return symKey->objectID; 2669 return symKey->objectID;
2322 } 2670 }
2323 2671
OLDNEW
« no previous file with comments | « mozilla/security/nss/lib/pk11wrap/pk11pub.h ('k') | mozilla/security/nss/lib/pk11wrap/pk11slot.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698