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 }
|