Print this page
9642 PKCS#11 softtoken should use explicit_bzero
Reviewed by: Dan McDonald <danmcd@joyent.com>
Reviewed by: Alex Wilson <alex.wilson@joyent.com>


   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.

  24  */
  25 
  26 #include <pthread.h>
  27 #include <stdlib.h>
  28 #include <string.h>
  29 #include <strings.h>
  30 #include <sys/types.h>
  31 #include <security/cryptoki.h>
  32 #include <sys/crypto/common.h>
  33 #include <aes_impl.h>
  34 #include <blowfish_impl.h>
  35 #include <des_impl.h>
  36 #include <arcfour.h>
  37 #include <cryptoutil.h>
  38 #include "softGlobal.h"
  39 #include "softSession.h"
  40 #include "softObject.h"
  41 #include "softDSA.h"
  42 #include "softRSA.h"
  43 #include "softDH.h"


 805                                 q += cbit;
 806                                 I[idx] = (CK_BYTE)(q & 0xff);
 807                                 cbit = (q > 0xff);
 808                         }
 809                 }
 810 
 811                 /*
 812                  * Step 7.
 813                  *  A += Ai
 814                  */
 815                 (void) memcpy(A + i*hashSize, Ai, AiLen);
 816         }
 817 
 818         /*
 819          * Step 8.
 820          * The final output of this process is the A buffer
 821          */
 822         (void) memcpy(keybuf, A, keysize);
 823 
 824 cleanup:
 825         if (A) {
 826                 bzero(A, Alen);
 827                 free(A);
 828         }
 829         if (Ai) {
 830                 bzero(Ai, AiLen);
 831                 free(Ai);
 832         }
 833         if (B) {
 834                 bzero(B, Blen);
 835                 free(B);
 836         }
 837         if (D) {
 838                 bzero(D, Dlen);
 839                 free(D);
 840         }
 841         if (I) {
 842                 bzero(I, Ilen);
 843                 free(I);
 844         }
 845         return (rv);
 846 }
 847 
 848 CK_RV
 849 soft_derivekey(soft_session_t *session_p, CK_MECHANISM_PTR pMechanism,
 850     soft_object_t *basekey_p, CK_ATTRIBUTE_PTR pTemplate,
 851     CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey)
 852 {
 853 
 854         CK_RV rv = CKR_OK;
 855         soft_object_t *secret_key;
 856         CK_MECHANISM digest_mech;
 857         CK_BYTE hash[SHA512_DIGEST_LENGTH]; /* space enough for all mechs */
 858         CK_ULONG hash_len = SHA512_DIGEST_LENGTH;
 859         CK_ULONG secret_key_len;
 860         CK_ULONG hash_size;
 861 
 862         switch (pMechanism->mechanism) {
 863         case CKM_DH_PKCS_DERIVE:
 864                 /*


1383                  * Append the block index to the salt as input
1384                  * to the PRF.  Block index should start at 1
1385                  * not 0.
1386                  */
1387                 *s++ = ((i+1) >> 24) & 0xff;
1388                 *s++ = ((i+1) >> 16) & 0xff;
1389                 *s++ = ((i+1) >> 8) & 0xff;
1390                 *s   = ((i+1)) & 0xff;
1391 
1392                 /*
1393                  * Adjust the key pointer so we always append the
1394                  * PRF output to the current key.
1395                  */
1396                 rv = do_prf(session_p, params, hmac_key,
1397                     salt, params->ulSaltSourceDataLen + 4, keydata,
1398                     ((i + 1) == blocks ? remainder : hLen));
1399 
1400                 keydata += hLen;
1401         }
1402         (void) soft_delete_object(session_p, hmac_key, B_FALSE, B_FALSE);
1403         free(salt);
1404 
1405         return (rv);
1406 }
1407 
1408 CK_RV
1409 soft_wrapkey(soft_session_t *session_p, CK_MECHANISM_PTR pMechanism,
1410                 soft_object_t *wrappingKey_p, soft_object_t *hkey_p,
1411                 CK_BYTE_PTR pWrappedKey, CK_ULONG_PTR pulWrappedKeyLen)
1412 {
1413         CK_RV           rv = CKR_OK;
1414         CK_ULONG        plain_len = 0;
1415         CK_BYTE_PTR     plain_data = NULL;
1416         CK_ULONG        padded_len = 0;
1417         CK_BYTE_PTR     padded_data = NULL;
1418         CK_ULONG        wkey_blksz = 1;         /* so modulo will work right */
1419 
1420         /* Check if the mechanism is supported. */
1421         switch (pMechanism->mechanism) {
1422         case CKM_DES_CBC_PAD:
1423         case CKM_DES3_CBC_PAD:


1518                                 goto cleanup_wrap;
1519                         }
1520                         (void) memset(padded_data, 0x0, padded_len);
1521                         (void) memcpy(padded_data, plain_data, plain_len);
1522                 }
1523                 break;
1524         default:
1525                 break;
1526         }
1527 
1528         rv = soft_encrypt_init(session_p, pMechanism, wrappingKey_p);
1529         if (rv != CKR_OK)
1530                 goto cleanup_wrap;
1531 
1532         rv = soft_encrypt(session_p, padded_data, padded_len,
1533             pWrappedKey, pulWrappedKeyLen);
1534 
1535 cleanup_wrap:
1536         if (padded_data != NULL && padded_len != plain_len) {
1537                 /* Clear buffer before returning to memory pool. */
1538                 (void) memset(padded_data, 0x0, padded_len);
1539                 free(padded_data);
1540         }
1541 
1542         if ((hkey_p->class != CKO_SECRET_KEY) && (plain_data != NULL)) {
1543                 /* Clear buffer before returning to memory pool. */
1544                 (void) memset(plain_data, 0x0, plain_len);
1545                 free(plain_data);
1546         }
1547 
1548         return (rv);
1549 }
1550 
1551 /*
1552  * Quick check for whether unwrapped key length is appropriate for key type
1553  * and whether it needs to be truncated (in case the wrapping function had
1554  * to pad the key prior to wrapping).
1555  */
1556 static CK_RV
1557 soft_unwrap_secret_len_check(CK_KEY_TYPE keytype, CK_MECHANISM_TYPE mechtype,
1558         CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount)
1559 {
1560         CK_ULONG        i;
1561         boolean_t       isValueLen = B_FALSE;
1562 
1563         /*
1564          * Based on the key type and the mech used to unwrap, need to
1565          * determine if CKA_VALUE_LEN should or should not be specified.


1805                                 goto cleanup_unwrap;
1806                         }
1807                 }
1808         } else {
1809                 /* BER-decode the object to be unwrapped. */
1810                 rv = soft_asn1_to_object(new_objp, plain_data, plain_len);
1811                 if (rv != CKR_OK)
1812                         goto cleanup_unwrap;
1813         }
1814 
1815         /* If it needs to be persistent, write it to the keystore */
1816         if (IS_TOKEN_OBJECT(new_objp)) {
1817                 persistent = B_TRUE;
1818                 rv = soft_put_object_to_keystore(new_objp);
1819                 if (rv != CKR_OK)
1820                         goto cleanup_unwrap;
1821         }
1822 
1823         if (new_objp->class != CKO_SECRET_KEY) {
1824                 /* Clear buffer before returning to memory pool. */
1825                 (void) memset(plain_data, 0x0, plain_len);
1826                 free(plain_data);
1827         }
1828 
1829         *phKey = (CK_OBJECT_HANDLE)new_objp;
1830 
1831         return (CKR_OK);
1832 
1833 cleanup_unwrap:
1834         /* The decrypted private key buffer must be freed explicitly. */
1835         if ((new_objp->class != CKO_SECRET_KEY) && (plain_data != NULL)) {
1836                 /* Clear buffer before returning to memory pool. */
1837                 (void) memset(plain_data, 0x0, plain_len);
1838                 free(plain_data);
1839         }
1840 
1841         /* sck and new_objp are indirectly free()d inside these functions */
1842         if (IS_TOKEN_OBJECT(new_objp))
1843                 soft_delete_token_object(new_objp, persistent, B_FALSE);
1844         else
1845                 soft_delete_object(session_p, new_objp, B_FALSE, B_FALSE);
1846 
1847         return (rv);
1848 }


   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  * Copyright (c) 2018, Joyent, Inc.
  25  */
  26 
  27 #include <pthread.h>
  28 #include <stdlib.h>
  29 #include <string.h>
  30 #include <strings.h>
  31 #include <sys/types.h>
  32 #include <security/cryptoki.h>
  33 #include <sys/crypto/common.h>
  34 #include <aes_impl.h>
  35 #include <blowfish_impl.h>
  36 #include <des_impl.h>
  37 #include <arcfour.h>
  38 #include <cryptoutil.h>
  39 #include "softGlobal.h"
  40 #include "softSession.h"
  41 #include "softObject.h"
  42 #include "softDSA.h"
  43 #include "softRSA.h"
  44 #include "softDH.h"


 806                                 q += cbit;
 807                                 I[idx] = (CK_BYTE)(q & 0xff);
 808                                 cbit = (q > 0xff);
 809                         }
 810                 }
 811 
 812                 /*
 813                  * Step 7.
 814                  *  A += Ai
 815                  */
 816                 (void) memcpy(A + i*hashSize, Ai, AiLen);
 817         }
 818 
 819         /*
 820          * Step 8.
 821          * The final output of this process is the A buffer
 822          */
 823         (void) memcpy(keybuf, A, keysize);
 824 
 825 cleanup:
 826         freezero(A, Alen);
 827         freezero(Ai, AiLen);
 828         freezero(B, Blen);
 829         freezero(D, Dlen);
 830         freezero(I, Ilen);















 831         return (rv);
 832 }
 833 
 834 CK_RV
 835 soft_derivekey(soft_session_t *session_p, CK_MECHANISM_PTR pMechanism,
 836     soft_object_t *basekey_p, CK_ATTRIBUTE_PTR pTemplate,
 837     CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey)
 838 {
 839 
 840         CK_RV rv = CKR_OK;
 841         soft_object_t *secret_key;
 842         CK_MECHANISM digest_mech;
 843         CK_BYTE hash[SHA512_DIGEST_LENGTH]; /* space enough for all mechs */
 844         CK_ULONG hash_len = SHA512_DIGEST_LENGTH;
 845         CK_ULONG secret_key_len;
 846         CK_ULONG hash_size;
 847 
 848         switch (pMechanism->mechanism) {
 849         case CKM_DH_PKCS_DERIVE:
 850                 /*


1369                  * Append the block index to the salt as input
1370                  * to the PRF.  Block index should start at 1
1371                  * not 0.
1372                  */
1373                 *s++ = ((i+1) >> 24) & 0xff;
1374                 *s++ = ((i+1) >> 16) & 0xff;
1375                 *s++ = ((i+1) >> 8) & 0xff;
1376                 *s   = ((i+1)) & 0xff;
1377 
1378                 /*
1379                  * Adjust the key pointer so we always append the
1380                  * PRF output to the current key.
1381                  */
1382                 rv = do_prf(session_p, params, hmac_key,
1383                     salt, params->ulSaltSourceDataLen + 4, keydata,
1384                     ((i + 1) == blocks ? remainder : hLen));
1385 
1386                 keydata += hLen;
1387         }
1388         (void) soft_delete_object(session_p, hmac_key, B_FALSE, B_FALSE);
1389         freezero(salt, params->ulSaltSourceDataLen);
1390 
1391         return (rv);
1392 }
1393 
1394 CK_RV
1395 soft_wrapkey(soft_session_t *session_p, CK_MECHANISM_PTR pMechanism,
1396                 soft_object_t *wrappingKey_p, soft_object_t *hkey_p,
1397                 CK_BYTE_PTR pWrappedKey, CK_ULONG_PTR pulWrappedKeyLen)
1398 {
1399         CK_RV           rv = CKR_OK;
1400         CK_ULONG        plain_len = 0;
1401         CK_BYTE_PTR     plain_data = NULL;
1402         CK_ULONG        padded_len = 0;
1403         CK_BYTE_PTR     padded_data = NULL;
1404         CK_ULONG        wkey_blksz = 1;         /* so modulo will work right */
1405 
1406         /* Check if the mechanism is supported. */
1407         switch (pMechanism->mechanism) {
1408         case CKM_DES_CBC_PAD:
1409         case CKM_DES3_CBC_PAD:


1504                                 goto cleanup_wrap;
1505                         }
1506                         (void) memset(padded_data, 0x0, padded_len);
1507                         (void) memcpy(padded_data, plain_data, plain_len);
1508                 }
1509                 break;
1510         default:
1511                 break;
1512         }
1513 
1514         rv = soft_encrypt_init(session_p, pMechanism, wrappingKey_p);
1515         if (rv != CKR_OK)
1516                 goto cleanup_wrap;
1517 
1518         rv = soft_encrypt(session_p, padded_data, padded_len,
1519             pWrappedKey, pulWrappedKeyLen);
1520 
1521 cleanup_wrap:
1522         if (padded_data != NULL && padded_len != plain_len) {
1523                 /* Clear buffer before returning to memory pool. */
1524                 freezero(padded_data, padded_len);

1525         }
1526 
1527         if ((hkey_p->class != CKO_SECRET_KEY) && (plain_data != NULL)) {
1528                 /* Clear buffer before returning to memory pool. */
1529                 freezero(plain_data, plain_len);

1530         }
1531 
1532         return (rv);
1533 }
1534 
1535 /*
1536  * Quick check for whether unwrapped key length is appropriate for key type
1537  * and whether it needs to be truncated (in case the wrapping function had
1538  * to pad the key prior to wrapping).
1539  */
1540 static CK_RV
1541 soft_unwrap_secret_len_check(CK_KEY_TYPE keytype, CK_MECHANISM_TYPE mechtype,
1542         CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount)
1543 {
1544         CK_ULONG        i;
1545         boolean_t       isValueLen = B_FALSE;
1546 
1547         /*
1548          * Based on the key type and the mech used to unwrap, need to
1549          * determine if CKA_VALUE_LEN should or should not be specified.


1789                                 goto cleanup_unwrap;
1790                         }
1791                 }
1792         } else {
1793                 /* BER-decode the object to be unwrapped. */
1794                 rv = soft_asn1_to_object(new_objp, plain_data, plain_len);
1795                 if (rv != CKR_OK)
1796                         goto cleanup_unwrap;
1797         }
1798 
1799         /* If it needs to be persistent, write it to the keystore */
1800         if (IS_TOKEN_OBJECT(new_objp)) {
1801                 persistent = B_TRUE;
1802                 rv = soft_put_object_to_keystore(new_objp);
1803                 if (rv != CKR_OK)
1804                         goto cleanup_unwrap;
1805         }
1806 
1807         if (new_objp->class != CKO_SECRET_KEY) {
1808                 /* Clear buffer before returning to memory pool. */
1809                 freezero(plain_data, plain_len);

1810         }
1811 
1812         *phKey = (CK_OBJECT_HANDLE)new_objp;
1813 
1814         return (CKR_OK);
1815 
1816 cleanup_unwrap:
1817         /* The decrypted private key buffer must be freed explicitly. */
1818         if ((new_objp->class != CKO_SECRET_KEY) && (plain_data != NULL)) {
1819                 /* Clear buffer before returning to memory pool. */
1820                 freezero(plain_data, plain_len);

1821         }
1822 
1823         /* sck and new_objp are indirectly free()d inside these functions */
1824         if (IS_TOKEN_OBJECT(new_objp))
1825                 soft_delete_token_object(new_objp, persistent, B_FALSE);
1826         else
1827                 soft_delete_object(session_p, new_objp, B_FALSE, B_FALSE);
1828 
1829         return (rv);
1830 }