Print this page
9156 Remove openssl dependency from pkcs11_tpm


   6  *
   7  * This program is free software; you can redistribute it and/or modify
   8  * it under the terms of the Common Public License as published by
   9  * IBM Corporation; either version 1 of the License, or (at your option)
  10  * any later version.
  11  *
  12  * This program is distributed in the hope that it will be useful,
  13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15  * Common Public License for more details.
  16  *
  17  * You should have received a copy of the Common Public License
  18  * along with this program; if not, a copy can be viewed at
  19  * http://www.opensource.org/licenses/cpl1.0.php.
  20  */
  21 /*
  22  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  * Copyright 2012 Milan Jurik. All rights reserved.
  25  * Copyright (c) 2016 by Delphix. All rights reserved.

  26  */
  27 
  28 #include <pthread.h>
  29 #include <string.h>
  30 
  31 #include <sys/types.h>
  32 #include <sys/stat.h>
  33 #include <uuid/uuid.h>
  34 #include <fcntl.h>
  35 #include <errno.h>
  36 #include <pwd.h>
  37 #include <syslog.h>
  38 
  39 #include <openssl/rsa.h>


  40 
  41 #include <tss/platform.h>
  42 #include <tss/tss_defines.h>
  43 #include <tss/tss_typedef.h>
  44 #include <tss/tss_structs.h>
  45 #include <tss/tss_error.h>
  46 #include <tss/tcs_error.h>
  47 #include <tss/tspi.h>
  48 #include <trousers/trousers.h>
  49 
  50 #include "tpmtok_int.h"
  51 #include "tpmtok_defs.h"
  52 
  53 #define MAX_RSA_KEYLENGTH 512
  54 
  55 extern void stlogit(char *fmt, ...);
  56 
  57 CK_RV token_rng(TSS_HCONTEXT, CK_BYTE *,  CK_ULONG);
  58 int tok_slot2local(CK_SLOT_ID);
  59 CK_RV token_specific_session(CK_SLOT_ID);


2723         CK_ULONG  * out_data_len,
2724         OBJECT    * key_obj)
2725 {
2726         TSS_HKEY        hKey;
2727         CK_RV           rc;
2728 
2729         if ((rc = token_rsa_load_key(hContext, key_obj, &hKey))) {
2730                 return (rc);
2731         }
2732 
2733         rc  = tpm_encrypt_data(hContext, hKey, in_data, in_data_len,
2734             out_data, out_data_len);
2735 
2736         return (rc);
2737 }
2738 
2739 /*
2740  * RSA Verify Recover
2741  *
2742  * Public key crypto is done in software, not by the TPM.
2743  * We bypass the TSPI library here in favor of calls directly
2744  * to OpenSSL because we don't want to add any padding, the in_data (signature)
2745  * already contains the data stream to be decrypted and is already
2746  * padded and formatted correctly.
2747  */
2748 CK_RV
2749 token_specific_rsa_verify_recover(
2750         TSS_HCONTEXT    hContext,
2751         CK_BYTE         *in_data,       /* signature */
2752         CK_ULONG        in_data_len,
2753         CK_BYTE         *out_data,      /* decrypted */
2754         CK_ULONG        *out_data_len,
2755         OBJECT          *key_obj)
2756 {
2757         TSS_HKEY        hKey;
2758         TSS_RESULT      result;
2759         CK_RV           rc;
2760         BYTE            *modulus;
2761         UINT32          modLen;
2762         RSA             *rsa = NULL;
2763         uchar_t         exp[] = { 0x01, 0x00, 0x01 };
2764         int             sslrv, num;
2765         BYTE            temp[MAX_RSA_KEYLENGTH];
2766         BYTE            outdata[MAX_RSA_KEYLENGTH];
2767         int             i;
2768 
2769         if ((rc = token_rsa_load_key(hContext, key_obj, &hKey))) {
2770                 return (rc);
2771         }
2772 
2773         if ((result = Tspi_GetAttribData(hKey, TSS_TSPATTRIB_RSAKEY_INFO,
2774             TSS_TSPATTRIB_KEYINFO_RSA_MODULUS, &modLen, &modulus))) {
2775                 stlogit("Tspi_GetAttribData: 0x%0x - %s",
2776                     result, Trspi_Error_String(result));
2777                 return (CKR_FUNCTION_FAILED);
2778         }
2779 
2780         if (in_data_len != modLen) {
2781                 rc = CKR_SIGNATURE_LEN_RANGE;
2782                 goto end;
2783         }
2784 
2785         rsa = RSA_new();
2786         if (rsa == NULL) {
2787                 rc = CKR_HOST_MEMORY;
2788                 goto end;
2789         }
2790 
2791         rsa->n = BN_bin2bn(modulus, modLen, rsa->n);
2792         rsa->e = BN_bin2bn(exp, sizeof (exp), rsa->e);
2793         if (rsa->n == NULL || rsa->e == NULL) {
2794                 rc = CKR_HOST_MEMORY;
2795                 goto end;
2796         }
2797 
2798         rsa->flags |= RSA_FLAG_SIGN_VER;
2799 
2800         /* use RSA_NO_PADDING because the data is already padded (PKCS1) */
2801         sslrv = RSA_public_encrypt(in_data_len, in_data, outdata,
2802             rsa, RSA_NO_PADDING);
2803         if (sslrv == -1) {
2804                 rc = CKR_FUNCTION_FAILED;
2805                 goto end;
2806         }
2807 
2808         /* Strip leading 0's before stripping the padding */
2809         for (i = 0; i < sslrv; i++)
2810                 if (outdata[i] != 0)
2811                         break;
2812 
2813         num = BN_num_bytes(rsa->n);
2814 
2815         /* Use OpenSSL function for stripping PKCS#1 padding */
2816         sslrv = RSA_padding_check_PKCS1_type_1(temp, sizeof (temp),
2817             &outdata[i], sslrv - i, num);
2818 
2819         if (sslrv < 0) {
2820                 rc = CKR_FUNCTION_FAILED;
2821                 goto end;
2822         }
2823 
2824         if (*out_data_len < sslrv) {
2825                 rc = CKR_BUFFER_TOO_SMALL;
2826                 *out_data_len = 0;
2827                 goto end;
2828         }
2829 
2830         /* The return code indicates the number of bytes remaining */
2831         (void) memcpy(out_data, temp, sslrv);
2832         *out_data_len = sslrv;
2833 end:
2834         Tspi_Context_FreeMemory(hContext, modulus);
2835         if (rsa)
2836                 RSA_free(rsa);
2837 
2838         return (rc);
2839 }


   6  *
   7  * This program is free software; you can redistribute it and/or modify
   8  * it under the terms of the Common Public License as published by
   9  * IBM Corporation; either version 1 of the License, or (at your option)
  10  * any later version.
  11  *
  12  * This program is distributed in the hope that it will be useful,
  13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15  * Common Public License for more details.
  16  *
  17  * You should have received a copy of the Common Public License
  18  * along with this program; if not, a copy can be viewed at
  19  * http://www.opensource.org/licenses/cpl1.0.php.
  20  */
  21 /*
  22  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  * Copyright 2012 Milan Jurik. All rights reserved.
  25  * Copyright (c) 2016 by Delphix. All rights reserved.
  26  * Copyright 2018 Jason King
  27  */
  28 
  29 #include <pthread.h>
  30 #include <string.h>
  31 
  32 #include <sys/types.h>
  33 #include <sys/stat.h>
  34 #include <uuid/uuid.h>
  35 #include <fcntl.h>
  36 #include <errno.h>
  37 #include <pwd.h>
  38 #include <syslog.h>
  39 
  40 #include <sys/crypto/common.h>    /* For CRYPTO_BYTES2BITS */
  41 #include <rsa_impl.h>
  42 #include <padding.h>
  43 
  44 #include <tss/platform.h>
  45 #include <tss/tss_defines.h>
  46 #include <tss/tss_typedef.h>
  47 #include <tss/tss_structs.h>
  48 #include <tss/tss_error.h>
  49 #include <tss/tcs_error.h>
  50 #include <tss/tspi.h>
  51 #include <trousers/trousers.h>
  52 
  53 #include "tpmtok_int.h"
  54 #include "tpmtok_defs.h"
  55 
  56 #define MAX_RSA_KEYLENGTH 512
  57 
  58 extern void stlogit(char *fmt, ...);
  59 
  60 CK_RV token_rng(TSS_HCONTEXT, CK_BYTE *,  CK_ULONG);
  61 int tok_slot2local(CK_SLOT_ID);
  62 CK_RV token_specific_session(CK_SLOT_ID);


2726         CK_ULONG  * out_data_len,
2727         OBJECT    * key_obj)
2728 {
2729         TSS_HKEY        hKey;
2730         CK_RV           rc;
2731 
2732         if ((rc = token_rsa_load_key(hContext, key_obj, &hKey))) {
2733                 return (rc);
2734         }
2735 
2736         rc  = tpm_encrypt_data(hContext, hKey, in_data, in_data_len,
2737             out_data, out_data_len);
2738 
2739         return (rc);
2740 }
2741 
2742 /*
2743  * RSA Verify Recover
2744  *
2745  * Public key crypto is done in software, not by the TPM.
2746  * We use libsoftcrypto and perform the RSA operations ourselves similar
2747  * to how pkcs11_softtoken performs the operation.


2748  */
2749 CK_RV
2750 token_specific_rsa_verify_recover(
2751         TSS_HCONTEXT    hContext,
2752         CK_BYTE_PTR     pSignature,
2753         CK_ULONG        ulSignatureLen,
2754         CK_BYTE_PTR     pData,
2755         CK_ULONG_PTR    pulDataLen,
2756         OBJECT          *key_obj)
2757 {
2758         TSS_HKEY        hKey;
2759         TSS_RESULT      result;
2760         CK_RV           rc;
2761         BYTE            *modulus;
2762         UINT32          modLen;
2763         RSAbytekey      rsa = { 0 };
2764         uchar_t         exp[] = { 0x01, 0x00, 0x01 };
2765         CK_BYTE         plain_data[MAX_RSA_KEYLENGTH];
2766         size_t          data_len;


2767 
2768         if ((rc = token_rsa_load_key(hContext, key_obj, &hKey))) {
2769                 return (rc);
2770         }
2771 
2772         if ((result = Tspi_GetAttribData(hKey, TSS_TSPATTRIB_RSAKEY_INFO,
2773             TSS_TSPATTRIB_KEYINFO_RSA_MODULUS, &modLen, &modulus))) {
2774                 stlogit("Tspi_GetAttribData: 0x%0x - %s",
2775                     result, Trspi_Error_String(result));
2776                 return (CKR_FUNCTION_FAILED);
2777         }
2778 
2779         if (ulSignatureLen != modLen) {
2780                 rc = CKR_SIGNATURE_LEN_RANGE;
2781                 goto end;
2782         }
2783 
2784         rsa.modulus = modulus;
2785         rsa.modulus_bits = CRYPTO_BYTES2BITS(modLen);
2786         rsa.pubexpo = exp;
2787         rsa.pubexpo_bytes = sizeof (exp);

2788 
2789         if ((rc = rsa_encrypt(&rsa, pSignature, modLen, plain_data)) != CKR_OK)



2790                 goto end;

2791 
2792         data_len = modLen;
2793         if ((rc = pkcs1_decode(PKCS1_VERIFY, plain_data, &data_len)) != CKR_OK)





2794                 goto end;

2795 
2796         (void) memcpy(pData, &plain_data[modLen - data_len], data_len);
2797         *pulDataLen = data_len;


2798 




















2799 end:
2800         Tspi_Context_FreeMemory(hContext, modulus);



2801         return (rc);
2802 }