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 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 Loading... |
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 Loading... |
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 ¶m, 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 ¶m, 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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |