147e946e7SWyllys Ingersoll /*
247e946e7SWyllys Ingersoll * The Initial Developer of the Original Code is International
347e946e7SWyllys Ingersoll * Business Machines Corporation. Portions created by IBM
447e946e7SWyllys Ingersoll * Corporation are Copyright (C) 2005 International Business
547e946e7SWyllys Ingersoll * Machines Corporation. All Rights Reserved.
647e946e7SWyllys Ingersoll *
747e946e7SWyllys Ingersoll * This program is free software; you can redistribute it and/or modify
847e946e7SWyllys Ingersoll * it under the terms of the Common Public License as published by
947e946e7SWyllys Ingersoll * IBM Corporation; either version 1 of the License, or (at your option)
1047e946e7SWyllys Ingersoll * any later version.
1147e946e7SWyllys Ingersoll *
1247e946e7SWyllys Ingersoll * This program is distributed in the hope that it will be useful,
1347e946e7SWyllys Ingersoll * but WITHOUT ANY WARRANTY; without even the implied warranty of
1447e946e7SWyllys Ingersoll * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1547e946e7SWyllys Ingersoll * Common Public License for more details.
1647e946e7SWyllys Ingersoll *
1747e946e7SWyllys Ingersoll * You should have received a copy of the Common Public License
1847e946e7SWyllys Ingersoll * along with this program; if not, a copy can be viewed at
1947e946e7SWyllys Ingersoll * http://www.opensource.org/licenses/cpl1.0.php.
2047e946e7SWyllys Ingersoll */
2147e946e7SWyllys Ingersoll /* (C) COPYRIGHT International Business Machines Corp. 2001, 2002, 2005 */
2247e946e7SWyllys Ingersoll /*
2347e946e7SWyllys Ingersoll * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
2447e946e7SWyllys Ingersoll * Use is subject to license terms.
2547e946e7SWyllys Ingersoll */
2647e946e7SWyllys Ingersoll
2747e946e7SWyllys Ingersoll #include "tpmtok_int.h"
2847e946e7SWyllys Ingersoll
29*ab8176c2SWyllys Ingersoll extern CK_RV
30*ab8176c2SWyllys Ingersoll token_specific_rsa_verify_recover(
31*ab8176c2SWyllys Ingersoll TSS_HCONTEXT hContext,
32*ab8176c2SWyllys Ingersoll CK_BYTE *in_data,
33*ab8176c2SWyllys Ingersoll CK_ULONG in_data_len,
34*ab8176c2SWyllys Ingersoll CK_BYTE *out_data,
35*ab8176c2SWyllys Ingersoll CK_ULONG *out_data_len,
36*ab8176c2SWyllys Ingersoll OBJECT *key_obj);
37*ab8176c2SWyllys Ingersoll
3847e946e7SWyllys Ingersoll CK_RV
ckm_rsa_key_pair_gen(TSS_HCONTEXT hContext,TEMPLATE * publ_tmpl,TEMPLATE * priv_tmpl)3947e946e7SWyllys Ingersoll ckm_rsa_key_pair_gen(TSS_HCONTEXT hContext,
4047e946e7SWyllys Ingersoll TEMPLATE * publ_tmpl,
4147e946e7SWyllys Ingersoll TEMPLATE * priv_tmpl)
4247e946e7SWyllys Ingersoll {
4347e946e7SWyllys Ingersoll CK_RV rc;
4447e946e7SWyllys Ingersoll
4547e946e7SWyllys Ingersoll rc = token_specific.t_rsa_generate_keypair(
4647e946e7SWyllys Ingersoll hContext, publ_tmpl, priv_tmpl);
4747e946e7SWyllys Ingersoll
4847e946e7SWyllys Ingersoll return (rc);
4947e946e7SWyllys Ingersoll }
5047e946e7SWyllys Ingersoll
5147e946e7SWyllys Ingersoll static CK_RV
ckm_rsa_encrypt(TSS_HCONTEXT hContext,CK_BYTE * in_data,CK_ULONG in_data_len,CK_BYTE * out_data,CK_ULONG * out_data_len,OBJECT * key_obj)5247e946e7SWyllys Ingersoll ckm_rsa_encrypt(
5347e946e7SWyllys Ingersoll TSS_HCONTEXT hContext,
5447e946e7SWyllys Ingersoll CK_BYTE * in_data,
5547e946e7SWyllys Ingersoll CK_ULONG in_data_len,
5647e946e7SWyllys Ingersoll CK_BYTE * out_data,
5747e946e7SWyllys Ingersoll CK_ULONG * out_data_len,
5847e946e7SWyllys Ingersoll OBJECT * key_obj)
5947e946e7SWyllys Ingersoll {
6047e946e7SWyllys Ingersoll CK_ATTRIBUTE * attr = NULL;
6147e946e7SWyllys Ingersoll CK_OBJECT_CLASS keyclass;
6247e946e7SWyllys Ingersoll CK_RV rc;
6347e946e7SWyllys Ingersoll
6447e946e7SWyllys Ingersoll rc = template_attribute_find(key_obj->template, CKA_CLASS, &attr);
6547e946e7SWyllys Ingersoll if (rc == FALSE) {
6647e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED);
6747e946e7SWyllys Ingersoll } else
6847e946e7SWyllys Ingersoll keyclass = *(CK_OBJECT_CLASS *)attr->pValue;
6947e946e7SWyllys Ingersoll
7047e946e7SWyllys Ingersoll if (keyclass != CKO_PUBLIC_KEY) {
7147e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED);
7247e946e7SWyllys Ingersoll }
7347e946e7SWyllys Ingersoll
7447e946e7SWyllys Ingersoll rc = token_specific.t_rsa_encrypt(hContext,
7547e946e7SWyllys Ingersoll in_data, in_data_len,
7647e946e7SWyllys Ingersoll out_data, out_data_len, key_obj);
7747e946e7SWyllys Ingersoll
7847e946e7SWyllys Ingersoll return (rc);
7947e946e7SWyllys Ingersoll }
8047e946e7SWyllys Ingersoll
8147e946e7SWyllys Ingersoll static CK_RV
ckm_rsa_decrypt(TSS_HCONTEXT hContext,CK_BYTE * in_data,CK_ULONG in_data_len,CK_BYTE * out_data,CK_ULONG * out_data_len,OBJECT * key_obj)8247e946e7SWyllys Ingersoll ckm_rsa_decrypt(
8347e946e7SWyllys Ingersoll TSS_HCONTEXT hContext,
8447e946e7SWyllys Ingersoll CK_BYTE * in_data,
8547e946e7SWyllys Ingersoll CK_ULONG in_data_len,
8647e946e7SWyllys Ingersoll CK_BYTE * out_data,
8747e946e7SWyllys Ingersoll CK_ULONG * out_data_len,
8847e946e7SWyllys Ingersoll OBJECT * key_obj) {
8947e946e7SWyllys Ingersoll CK_ATTRIBUTE * attr = NULL;
9047e946e7SWyllys Ingersoll CK_OBJECT_CLASS keyclass;
9147e946e7SWyllys Ingersoll CK_RV rc;
9247e946e7SWyllys Ingersoll
9347e946e7SWyllys Ingersoll
9447e946e7SWyllys Ingersoll rc = template_attribute_find(key_obj->template, CKA_CLASS, &attr);
9547e946e7SWyllys Ingersoll if (rc == FALSE) {
9647e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED);
9747e946e7SWyllys Ingersoll }
9847e946e7SWyllys Ingersoll else
9947e946e7SWyllys Ingersoll keyclass = *(CK_OBJECT_CLASS *)attr->pValue;
10047e946e7SWyllys Ingersoll
10147e946e7SWyllys Ingersoll // this had better be a private key
10247e946e7SWyllys Ingersoll //
10347e946e7SWyllys Ingersoll if (keyclass != CKO_PRIVATE_KEY) {
10447e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED);
10547e946e7SWyllys Ingersoll }
10647e946e7SWyllys Ingersoll rc = token_specific.t_rsa_decrypt(hContext,
10747e946e7SWyllys Ingersoll in_data, in_data_len,
10847e946e7SWyllys Ingersoll out_data, out_data_len, key_obj);
10947e946e7SWyllys Ingersoll
11047e946e7SWyllys Ingersoll return (rc);
11147e946e7SWyllys Ingersoll }
11247e946e7SWyllys Ingersoll
11347e946e7SWyllys Ingersoll static CK_RV
ckm_rsa_sign(TSS_HCONTEXT hContext,CK_BYTE * in_data,CK_ULONG in_data_len,CK_BYTE * out_data,CK_ULONG * out_data_len,OBJECT * key_obj)11447e946e7SWyllys Ingersoll ckm_rsa_sign(
11547e946e7SWyllys Ingersoll TSS_HCONTEXT hContext,
11647e946e7SWyllys Ingersoll CK_BYTE * in_data,
11747e946e7SWyllys Ingersoll CK_ULONG in_data_len,
11847e946e7SWyllys Ingersoll CK_BYTE * out_data,
11947e946e7SWyllys Ingersoll CK_ULONG * out_data_len,
12047e946e7SWyllys Ingersoll OBJECT * key_obj) {
12147e946e7SWyllys Ingersoll CK_ATTRIBUTE * attr = NULL;
12247e946e7SWyllys Ingersoll CK_OBJECT_CLASS keyclass;
12347e946e7SWyllys Ingersoll CK_RV rc;
12447e946e7SWyllys Ingersoll
12547e946e7SWyllys Ingersoll
12647e946e7SWyllys Ingersoll rc = template_attribute_find(key_obj->template, CKA_CLASS, &attr);
12747e946e7SWyllys Ingersoll if (rc == FALSE) {
12847e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED);
129*ab8176c2SWyllys Ingersoll } else {
13047e946e7SWyllys Ingersoll keyclass = *(CK_OBJECT_CLASS *)attr->pValue;
131*ab8176c2SWyllys Ingersoll }
13247e946e7SWyllys Ingersoll
13347e946e7SWyllys Ingersoll if (keyclass != CKO_PRIVATE_KEY) {
13447e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED);
13547e946e7SWyllys Ingersoll }
13647e946e7SWyllys Ingersoll rc = token_specific.t_rsa_sign(
13747e946e7SWyllys Ingersoll hContext, in_data, in_data_len, out_data,
13847e946e7SWyllys Ingersoll out_data_len, key_obj);
13947e946e7SWyllys Ingersoll
14047e946e7SWyllys Ingersoll return (rc);
14147e946e7SWyllys Ingersoll }
14247e946e7SWyllys Ingersoll
14347e946e7SWyllys Ingersoll static CK_RV
ckm_rsa_verify(TSS_HCONTEXT hContext,CK_BYTE * in_data,CK_ULONG in_data_len,CK_BYTE * out_data,CK_ULONG out_data_len,OBJECT * key_obj)14447e946e7SWyllys Ingersoll ckm_rsa_verify(
14547e946e7SWyllys Ingersoll TSS_HCONTEXT hContext,
14647e946e7SWyllys Ingersoll CK_BYTE * in_data,
14747e946e7SWyllys Ingersoll CK_ULONG in_data_len,
14847e946e7SWyllys Ingersoll CK_BYTE * out_data,
14947e946e7SWyllys Ingersoll CK_ULONG out_data_len,
15047e946e7SWyllys Ingersoll OBJECT * key_obj) {
15147e946e7SWyllys Ingersoll CK_ATTRIBUTE * attr = NULL;
15247e946e7SWyllys Ingersoll CK_OBJECT_CLASS keyclass;
15347e946e7SWyllys Ingersoll CK_RV rc;
15447e946e7SWyllys Ingersoll
15547e946e7SWyllys Ingersoll
15647e946e7SWyllys Ingersoll rc = template_attribute_find(key_obj->template, CKA_CLASS, &attr);
15747e946e7SWyllys Ingersoll if (rc == FALSE) {
15847e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED);
15947e946e7SWyllys Ingersoll }
16047e946e7SWyllys Ingersoll else
16147e946e7SWyllys Ingersoll keyclass = *(CK_OBJECT_CLASS *)attr->pValue;
16247e946e7SWyllys Ingersoll
16347e946e7SWyllys Ingersoll if (keyclass != CKO_PUBLIC_KEY) {
16447e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED);
16547e946e7SWyllys Ingersoll }
16647e946e7SWyllys Ingersoll rc = token_specific.t_rsa_verify(hContext,
16747e946e7SWyllys Ingersoll in_data, in_data_len, out_data,
16847e946e7SWyllys Ingersoll out_data_len, key_obj);
16947e946e7SWyllys Ingersoll
17047e946e7SWyllys Ingersoll return (rc);
17147e946e7SWyllys Ingersoll }
17247e946e7SWyllys Ingersoll
17347e946e7SWyllys Ingersoll /*ARGSUSED*/
17447e946e7SWyllys Ingersoll CK_RV
rsa_pkcs_encrypt(SESSION * sess,CK_BBOOL length_only,ENCR_DECR_CONTEXT * ctx,CK_BYTE * in_data,CK_ULONG in_data_len,CK_BYTE * out_data,CK_ULONG * out_data_len)17547e946e7SWyllys Ingersoll rsa_pkcs_encrypt(SESSION *sess,
17647e946e7SWyllys Ingersoll CK_BBOOL length_only,
17747e946e7SWyllys Ingersoll ENCR_DECR_CONTEXT *ctx,
17847e946e7SWyllys Ingersoll CK_BYTE *in_data,
17947e946e7SWyllys Ingersoll CK_ULONG in_data_len,
18047e946e7SWyllys Ingersoll CK_BYTE *out_data,
181*ab8176c2SWyllys Ingersoll CK_ULONG *out_data_len)
182*ab8176c2SWyllys Ingersoll {
18347e946e7SWyllys Ingersoll OBJECT *key_obj = NULL;
18447e946e7SWyllys Ingersoll CK_ATTRIBUTE *attr = NULL;
18547e946e7SWyllys Ingersoll CK_ULONG modulus_bytes;
18647e946e7SWyllys Ingersoll CK_BBOOL flag;
18747e946e7SWyllys Ingersoll CK_RV rc;
18847e946e7SWyllys Ingersoll
18947e946e7SWyllys Ingersoll
19047e946e7SWyllys Ingersoll rc = object_mgr_find_in_map1(sess->hContext, ctx->key, &key_obj);
19147e946e7SWyllys Ingersoll if (rc != CKR_OK) {
19247e946e7SWyllys Ingersoll return (rc);
19347e946e7SWyllys Ingersoll }
19447e946e7SWyllys Ingersoll flag = template_attribute_find(key_obj->template, CKA_MODULUS, &attr);
19547e946e7SWyllys Ingersoll if (flag == FALSE) {
19647e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED);
197*ab8176c2SWyllys Ingersoll } else {
19847e946e7SWyllys Ingersoll modulus_bytes = attr->ulValueLen;
19947e946e7SWyllys Ingersoll }
20047e946e7SWyllys Ingersoll
20147e946e7SWyllys Ingersoll if (length_only == TRUE) {
202*ab8176c2SWyllys Ingersoll *out_data_len = modulus_bytes;
20347e946e7SWyllys Ingersoll return (CKR_OK);
20447e946e7SWyllys Ingersoll }
20547e946e7SWyllys Ingersoll
20647e946e7SWyllys Ingersoll if (*out_data_len < modulus_bytes) {
207*ab8176c2SWyllys Ingersoll *out_data_len = modulus_bytes;
20847e946e7SWyllys Ingersoll return (CKR_BUFFER_TOO_SMALL);
20947e946e7SWyllys Ingersoll }
21047e946e7SWyllys Ingersoll
21147e946e7SWyllys Ingersoll rc = ckm_rsa_encrypt(sess->hContext, in_data, in_data_len, out_data,
21247e946e7SWyllys Ingersoll out_data_len, key_obj);
21347e946e7SWyllys Ingersoll return (rc);
21447e946e7SWyllys Ingersoll }
21547e946e7SWyllys Ingersoll
21647e946e7SWyllys Ingersoll /*ARGSUSED*/
21747e946e7SWyllys Ingersoll CK_RV
rsa_pkcs_decrypt(SESSION * sess,CK_BBOOL length_only,ENCR_DECR_CONTEXT * ctx,CK_BYTE * in_data,CK_ULONG in_data_len,CK_BYTE * out_data,CK_ULONG * out_data_len)21847e946e7SWyllys Ingersoll rsa_pkcs_decrypt(SESSION *sess,
21947e946e7SWyllys Ingersoll CK_BBOOL length_only,
22047e946e7SWyllys Ingersoll ENCR_DECR_CONTEXT *ctx,
22147e946e7SWyllys Ingersoll CK_BYTE *in_data,
22247e946e7SWyllys Ingersoll CK_ULONG in_data_len,
22347e946e7SWyllys Ingersoll CK_BYTE *out_data,
22447e946e7SWyllys Ingersoll CK_ULONG *out_data_len)
22547e946e7SWyllys Ingersoll {
22647e946e7SWyllys Ingersoll OBJECT *key_obj = NULL;
22747e946e7SWyllys Ingersoll CK_ATTRIBUTE *attr = NULL;
22847e946e7SWyllys Ingersoll CK_ULONG modulus_bytes;
22947e946e7SWyllys Ingersoll CK_BBOOL flag;
23047e946e7SWyllys Ingersoll CK_RV rc;
23147e946e7SWyllys Ingersoll
23247e946e7SWyllys Ingersoll
23347e946e7SWyllys Ingersoll rc = object_mgr_find_in_map1(sess->hContext, ctx->key, &key_obj);
23447e946e7SWyllys Ingersoll if (rc != CKR_OK) {
23547e946e7SWyllys Ingersoll return (rc);
23647e946e7SWyllys Ingersoll }
23747e946e7SWyllys Ingersoll flag = template_attribute_find(key_obj->template, CKA_MODULUS, &attr);
23847e946e7SWyllys Ingersoll if (flag == FALSE)
23947e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED);
24047e946e7SWyllys Ingersoll else
24147e946e7SWyllys Ingersoll modulus_bytes = attr->ulValueLen;
24247e946e7SWyllys Ingersoll
24347e946e7SWyllys Ingersoll if (in_data_len != modulus_bytes) {
24447e946e7SWyllys Ingersoll return (CKR_ENCRYPTED_DATA_LEN_RANGE);
24547e946e7SWyllys Ingersoll }
24647e946e7SWyllys Ingersoll if (length_only == TRUE) {
24747e946e7SWyllys Ingersoll *out_data_len = modulus_bytes - 11;
24847e946e7SWyllys Ingersoll return (CKR_OK);
24947e946e7SWyllys Ingersoll }
25047e946e7SWyllys Ingersoll
25147e946e7SWyllys Ingersoll rc = ckm_rsa_decrypt(sess->hContext, in_data,
25247e946e7SWyllys Ingersoll modulus_bytes, out_data,
25347e946e7SWyllys Ingersoll out_data_len, key_obj);
25447e946e7SWyllys Ingersoll
25547e946e7SWyllys Ingersoll if (rc == CKR_DATA_LEN_RANGE) {
25647e946e7SWyllys Ingersoll return (CKR_ENCRYPTED_DATA_LEN_RANGE);
25747e946e7SWyllys Ingersoll }
25847e946e7SWyllys Ingersoll return (rc);
25947e946e7SWyllys Ingersoll }
26047e946e7SWyllys Ingersoll
26147e946e7SWyllys Ingersoll CK_RV
rsa_pkcs_sign(SESSION * sess,CK_BBOOL length_only,SIGN_VERIFY_CONTEXT * ctx,CK_BYTE * in_data,CK_ULONG in_data_len,CK_BYTE * out_data,CK_ULONG * out_data_len)26247e946e7SWyllys Ingersoll rsa_pkcs_sign(SESSION *sess,
26347e946e7SWyllys Ingersoll CK_BBOOL length_only,
26447e946e7SWyllys Ingersoll SIGN_VERIFY_CONTEXT *ctx,
26547e946e7SWyllys Ingersoll CK_BYTE *in_data,
26647e946e7SWyllys Ingersoll CK_ULONG in_data_len,
26747e946e7SWyllys Ingersoll CK_BYTE *out_data,
26847e946e7SWyllys Ingersoll CK_ULONG *out_data_len)
26947e946e7SWyllys Ingersoll {
27047e946e7SWyllys Ingersoll OBJECT *key_obj = NULL;
27147e946e7SWyllys Ingersoll CK_ATTRIBUTE *attr = NULL;
27247e946e7SWyllys Ingersoll CK_ULONG modulus_bytes;
27347e946e7SWyllys Ingersoll CK_BBOOL flag;
27447e946e7SWyllys Ingersoll CK_RV rc;
27547e946e7SWyllys Ingersoll
27647e946e7SWyllys Ingersoll
27747e946e7SWyllys Ingersoll if (! sess || ! ctx || ! out_data_len) {
27847e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED);
27947e946e7SWyllys Ingersoll }
28047e946e7SWyllys Ingersoll rc = object_mgr_find_in_map1(sess->hContext, ctx->key, &key_obj);
28147e946e7SWyllys Ingersoll if (rc != CKR_OK) {
28247e946e7SWyllys Ingersoll return (rc);
28347e946e7SWyllys Ingersoll }
28447e946e7SWyllys Ingersoll flag = template_attribute_find(key_obj->template, CKA_MODULUS, &attr);
28547e946e7SWyllys Ingersoll if (flag == FALSE)
28647e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED);
28747e946e7SWyllys Ingersoll else
28847e946e7SWyllys Ingersoll modulus_bytes = attr->ulValueLen;
28947e946e7SWyllys Ingersoll
29047e946e7SWyllys Ingersoll if (length_only == TRUE) {
29147e946e7SWyllys Ingersoll *out_data_len = modulus_bytes;
29247e946e7SWyllys Ingersoll return (CKR_OK);
29347e946e7SWyllys Ingersoll }
29447e946e7SWyllys Ingersoll
29547e946e7SWyllys Ingersoll if (*out_data_len < modulus_bytes) {
29647e946e7SWyllys Ingersoll *out_data_len = modulus_bytes;
29747e946e7SWyllys Ingersoll return (CKR_BUFFER_TOO_SMALL);
29847e946e7SWyllys Ingersoll }
29947e946e7SWyllys Ingersoll
30047e946e7SWyllys Ingersoll rc = ckm_rsa_sign(sess->hContext, in_data, in_data_len, out_data,
30147e946e7SWyllys Ingersoll out_data_len, key_obj);
30247e946e7SWyllys Ingersoll return (rc);
30347e946e7SWyllys Ingersoll }
30447e946e7SWyllys Ingersoll
30547e946e7SWyllys Ingersoll /*ARGSUSED*/
30647e946e7SWyllys Ingersoll CK_RV
rsa_pkcs_verify(SESSION * sess,SIGN_VERIFY_CONTEXT * ctx,CK_BYTE * in_data,CK_ULONG in_data_len,CK_BYTE * signature,CK_ULONG sig_len)30747e946e7SWyllys Ingersoll rsa_pkcs_verify(SESSION * sess,
30847e946e7SWyllys Ingersoll SIGN_VERIFY_CONTEXT * ctx,
30947e946e7SWyllys Ingersoll CK_BYTE * in_data,
31047e946e7SWyllys Ingersoll CK_ULONG in_data_len,
31147e946e7SWyllys Ingersoll CK_BYTE * signature,
31247e946e7SWyllys Ingersoll CK_ULONG sig_len)
31347e946e7SWyllys Ingersoll {
31447e946e7SWyllys Ingersoll OBJECT *key_obj = NULL;
31547e946e7SWyllys Ingersoll CK_ATTRIBUTE *attr = NULL;
31647e946e7SWyllys Ingersoll CK_ULONG modulus_bytes;
31747e946e7SWyllys Ingersoll CK_BBOOL flag;
31847e946e7SWyllys Ingersoll CK_RV rc;
31947e946e7SWyllys Ingersoll
32047e946e7SWyllys Ingersoll rc = object_mgr_find_in_map1(sess->hContext, ctx->key, &key_obj);
32147e946e7SWyllys Ingersoll if (rc != CKR_OK) {
32247e946e7SWyllys Ingersoll return (rc);
32347e946e7SWyllys Ingersoll }
32447e946e7SWyllys Ingersoll flag = template_attribute_find(key_obj->template, CKA_MODULUS, &attr);
32547e946e7SWyllys Ingersoll if (flag == FALSE) {
32647e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED);
32747e946e7SWyllys Ingersoll }
32847e946e7SWyllys Ingersoll else
32947e946e7SWyllys Ingersoll modulus_bytes = attr->ulValueLen;
33047e946e7SWyllys Ingersoll
33147e946e7SWyllys Ingersoll // check input data length restrictions
33247e946e7SWyllys Ingersoll //
33347e946e7SWyllys Ingersoll if (sig_len != modulus_bytes) {
33447e946e7SWyllys Ingersoll return (CKR_SIGNATURE_LEN_RANGE);
33547e946e7SWyllys Ingersoll }
33647e946e7SWyllys Ingersoll // verify is a public key operation --> encrypt
33747e946e7SWyllys Ingersoll //
33847e946e7SWyllys Ingersoll rc = ckm_rsa_verify(sess->hContext, in_data, in_data_len, signature,
33947e946e7SWyllys Ingersoll sig_len, key_obj);
34047e946e7SWyllys Ingersoll
34147e946e7SWyllys Ingersoll return (rc);
34247e946e7SWyllys Ingersoll }
34347e946e7SWyllys Ingersoll
34447e946e7SWyllys Ingersoll CK_RV
rsa_pkcs_verify_recover(SESSION * sess,CK_BBOOL length_only,SIGN_VERIFY_CONTEXT * ctx,CK_BYTE * signature,CK_ULONG sig_len,CK_BYTE * out_data,CK_ULONG * out_data_len)345*ab8176c2SWyllys Ingersoll rsa_pkcs_verify_recover(SESSION *sess,
346*ab8176c2SWyllys Ingersoll CK_BBOOL length_only,
347*ab8176c2SWyllys Ingersoll SIGN_VERIFY_CONTEXT *ctx,
348*ab8176c2SWyllys Ingersoll CK_BYTE *signature,
349*ab8176c2SWyllys Ingersoll CK_ULONG sig_len,
350*ab8176c2SWyllys Ingersoll CK_BYTE *out_data,
351*ab8176c2SWyllys Ingersoll CK_ULONG *out_data_len)
35247e946e7SWyllys Ingersoll {
353*ab8176c2SWyllys Ingersoll OBJECT *key_obj = NULL;
354*ab8176c2SWyllys Ingersoll CK_ATTRIBUTE *attr = NULL;
355*ab8176c2SWyllys Ingersoll CK_ULONG modulus_bytes;
356*ab8176c2SWyllys Ingersoll CK_BBOOL flag;
357*ab8176c2SWyllys Ingersoll CK_RV rc;
35847e946e7SWyllys Ingersoll
35947e946e7SWyllys Ingersoll if (! sess || ! ctx || ! out_data_len) {
36047e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED);
36147e946e7SWyllys Ingersoll }
36247e946e7SWyllys Ingersoll rc = object_mgr_find_in_map1(sess->hContext, ctx->key, &key_obj);
36347e946e7SWyllys Ingersoll if (rc != CKR_OK) {
36447e946e7SWyllys Ingersoll return (rc);
36547e946e7SWyllys Ingersoll }
36647e946e7SWyllys Ingersoll flag = template_attribute_find(key_obj->template, CKA_MODULUS, &attr);
36747e946e7SWyllys Ingersoll if (flag == FALSE) {
36847e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED);
36947e946e7SWyllys Ingersoll }
37047e946e7SWyllys Ingersoll else
37147e946e7SWyllys Ingersoll modulus_bytes = attr->ulValueLen;
37247e946e7SWyllys Ingersoll
37347e946e7SWyllys Ingersoll if (sig_len != modulus_bytes) {
37447e946e7SWyllys Ingersoll return (CKR_SIGNATURE_LEN_RANGE);
37547e946e7SWyllys Ingersoll }
37647e946e7SWyllys Ingersoll if (length_only == TRUE) {
37747e946e7SWyllys Ingersoll *out_data_len = modulus_bytes;
37847e946e7SWyllys Ingersoll return (CKR_OK);
37947e946e7SWyllys Ingersoll }
38047e946e7SWyllys Ingersoll
381*ab8176c2SWyllys Ingersoll rc = token_specific_rsa_verify_recover(sess->hContext,
382*ab8176c2SWyllys Ingersoll signature, modulus_bytes, out_data, out_data_len, key_obj);
38347e946e7SWyllys Ingersoll
38447e946e7SWyllys Ingersoll return (rc);
38547e946e7SWyllys Ingersoll }
38647e946e7SWyllys Ingersoll
38747e946e7SWyllys Ingersoll CK_RV
rsa_hash_pkcs_sign(SESSION * sess,CK_BBOOL length_only,SIGN_VERIFY_CONTEXT * ctx,CK_BYTE * in_data,CK_ULONG in_data_len,CK_BYTE * signature,CK_ULONG * sig_len)38847e946e7SWyllys Ingersoll rsa_hash_pkcs_sign(SESSION * sess,
38947e946e7SWyllys Ingersoll CK_BBOOL length_only,
39047e946e7SWyllys Ingersoll SIGN_VERIFY_CONTEXT * ctx,
39147e946e7SWyllys Ingersoll CK_BYTE * in_data,
39247e946e7SWyllys Ingersoll CK_ULONG in_data_len,
39347e946e7SWyllys Ingersoll CK_BYTE * signature,
39447e946e7SWyllys Ingersoll CK_ULONG * sig_len)
39547e946e7SWyllys Ingersoll {
39647e946e7SWyllys Ingersoll CK_BYTE * ber_data = NULL;
39747e946e7SWyllys Ingersoll CK_BYTE * octet_str = NULL;
39847e946e7SWyllys Ingersoll CK_BYTE * oid = NULL;
39947e946e7SWyllys Ingersoll CK_BYTE * tmp = NULL;
40047e946e7SWyllys Ingersoll
40147e946e7SWyllys Ingersoll CK_ULONG buf1[16];
40247e946e7SWyllys Ingersoll
40347e946e7SWyllys Ingersoll CK_BYTE hash[SHA1_DIGEST_LENGTH];
40447e946e7SWyllys Ingersoll DIGEST_CONTEXT digest_ctx;
40547e946e7SWyllys Ingersoll SIGN_VERIFY_CONTEXT sign_ctx;
40647e946e7SWyllys Ingersoll CK_MECHANISM digest_mech;
40747e946e7SWyllys Ingersoll CK_MECHANISM sign_mech;
40847e946e7SWyllys Ingersoll CK_ULONG ber_data_len, hash_len, octet_str_len, oid_len;
40947e946e7SWyllys Ingersoll CK_RV rc;
41047e946e7SWyllys Ingersoll
41147e946e7SWyllys Ingersoll if (! sess || ! ctx || ! in_data) {
41247e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED);
41347e946e7SWyllys Ingersoll }
41447e946e7SWyllys Ingersoll (void) memset(&digest_ctx, 0x0, sizeof (digest_ctx));
41547e946e7SWyllys Ingersoll (void) memset(&sign_ctx, 0x0, sizeof (sign_ctx));
41647e946e7SWyllys Ingersoll
41747e946e7SWyllys Ingersoll if (ctx->mech.mechanism == CKM_MD5_RSA_PKCS) {
41847e946e7SWyllys Ingersoll digest_mech.mechanism = CKM_MD5;
41947e946e7SWyllys Ingersoll oid = ber_AlgMd5;
42047e946e7SWyllys Ingersoll oid_len = ber_AlgMd5Len;
42147e946e7SWyllys Ingersoll hash_len = MD5_DIGEST_LENGTH;
42247e946e7SWyllys Ingersoll } else {
42347e946e7SWyllys Ingersoll digest_mech.mechanism = CKM_SHA_1;
42447e946e7SWyllys Ingersoll oid = ber_AlgSha1;
42547e946e7SWyllys Ingersoll oid_len = ber_AlgSha1Len;
42647e946e7SWyllys Ingersoll hash_len = SHA1_DIGEST_LENGTH;
42747e946e7SWyllys Ingersoll }
42847e946e7SWyllys Ingersoll
42947e946e7SWyllys Ingersoll digest_mech.ulParameterLen = 0;
43047e946e7SWyllys Ingersoll digest_mech.pParameter = NULL;
43147e946e7SWyllys Ingersoll
43247e946e7SWyllys Ingersoll rc = digest_mgr_init(sess, &digest_ctx, &digest_mech);
43347e946e7SWyllys Ingersoll if (rc != CKR_OK) {
43447e946e7SWyllys Ingersoll goto error;
43547e946e7SWyllys Ingersoll }
43647e946e7SWyllys Ingersoll rc = digest_mgr_digest(sess, length_only, &digest_ctx, in_data,
43747e946e7SWyllys Ingersoll in_data_len, hash, &hash_len);
43847e946e7SWyllys Ingersoll if (rc != CKR_OK)
43947e946e7SWyllys Ingersoll goto error;
44047e946e7SWyllys Ingersoll
44147e946e7SWyllys Ingersoll rc = ber_encode_OCTET_STRING(FALSE, &octet_str, &octet_str_len,
44247e946e7SWyllys Ingersoll hash, hash_len);
44347e946e7SWyllys Ingersoll if (rc != CKR_OK) {
44447e946e7SWyllys Ingersoll goto error;
44547e946e7SWyllys Ingersoll }
44647e946e7SWyllys Ingersoll tmp = (CK_BYTE *)buf1;
44747e946e7SWyllys Ingersoll (void) memcpy(tmp, oid, oid_len);
44847e946e7SWyllys Ingersoll (void) memcpy(tmp + oid_len, octet_str, octet_str_len);
44947e946e7SWyllys Ingersoll
45047e946e7SWyllys Ingersoll rc = ber_encode_SEQUENCE(FALSE, &ber_data, &ber_data_len,
45147e946e7SWyllys Ingersoll tmp, (oid_len + octet_str_len));
45247e946e7SWyllys Ingersoll if (rc != CKR_OK)
45347e946e7SWyllys Ingersoll goto error;
45447e946e7SWyllys Ingersoll
45547e946e7SWyllys Ingersoll sign_mech.mechanism = CKM_RSA_PKCS;
45647e946e7SWyllys Ingersoll sign_mech.ulParameterLen = 0;
45747e946e7SWyllys Ingersoll sign_mech.pParameter = NULL;
45847e946e7SWyllys Ingersoll
45947e946e7SWyllys Ingersoll rc = sign_mgr_init(sess, &sign_ctx, &sign_mech, FALSE, ctx->key);
46047e946e7SWyllys Ingersoll if (rc != CKR_OK)
46147e946e7SWyllys Ingersoll goto error;
46247e946e7SWyllys Ingersoll
46347e946e7SWyllys Ingersoll rc = sign_mgr_sign(sess, length_only, &sign_ctx, ber_data,
46447e946e7SWyllys Ingersoll ber_data_len, signature, sig_len);
46547e946e7SWyllys Ingersoll
46647e946e7SWyllys Ingersoll error:
46747e946e7SWyllys Ingersoll if (octet_str) free(octet_str);
46847e946e7SWyllys Ingersoll if (ber_data) free(ber_data);
46947e946e7SWyllys Ingersoll (void) digest_mgr_cleanup(&digest_ctx);
47047e946e7SWyllys Ingersoll (void) sign_mgr_cleanup(&sign_ctx);
47147e946e7SWyllys Ingersoll return (rc);
47247e946e7SWyllys Ingersoll }
47347e946e7SWyllys Ingersoll
47447e946e7SWyllys Ingersoll CK_RV
rsa_hash_pkcs_sign_update(SESSION * sess,SIGN_VERIFY_CONTEXT * ctx,CK_BYTE * in_data,CK_ULONG in_data_len)47547e946e7SWyllys Ingersoll rsa_hash_pkcs_sign_update(
47647e946e7SWyllys Ingersoll SESSION * sess,
47747e946e7SWyllys Ingersoll SIGN_VERIFY_CONTEXT * ctx,
47847e946e7SWyllys Ingersoll CK_BYTE * in_data,
47947e946e7SWyllys Ingersoll CK_ULONG in_data_len)
48047e946e7SWyllys Ingersoll {
48147e946e7SWyllys Ingersoll RSA_DIGEST_CONTEXT * context = NULL;
48247e946e7SWyllys Ingersoll CK_MECHANISM digest_mech;
48347e946e7SWyllys Ingersoll CK_RV rc;
48447e946e7SWyllys Ingersoll
48547e946e7SWyllys Ingersoll if (! sess || ! ctx || ! in_data)
48647e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED);
48747e946e7SWyllys Ingersoll
48847e946e7SWyllys Ingersoll context = (RSA_DIGEST_CONTEXT *)ctx->context;
48947e946e7SWyllys Ingersoll
49047e946e7SWyllys Ingersoll if (context->flag == FALSE) {
49147e946e7SWyllys Ingersoll if (ctx->mech.mechanism == CKM_MD5_RSA_PKCS)
49247e946e7SWyllys Ingersoll digest_mech.mechanism = CKM_MD5;
49347e946e7SWyllys Ingersoll else
49447e946e7SWyllys Ingersoll digest_mech.mechanism = CKM_SHA_1;
49547e946e7SWyllys Ingersoll
49647e946e7SWyllys Ingersoll digest_mech.ulParameterLen = 0;
49747e946e7SWyllys Ingersoll digest_mech.pParameter = NULL;
49847e946e7SWyllys Ingersoll
49947e946e7SWyllys Ingersoll rc = digest_mgr_init(sess, &context->hash_context,
50047e946e7SWyllys Ingersoll &digest_mech);
50147e946e7SWyllys Ingersoll if (rc != CKR_OK) {
50247e946e7SWyllys Ingersoll goto error;
50347e946e7SWyllys Ingersoll }
50447e946e7SWyllys Ingersoll context->flag = TRUE;
50547e946e7SWyllys Ingersoll }
50647e946e7SWyllys Ingersoll
50747e946e7SWyllys Ingersoll rc = digest_mgr_digest_update(sess, &context->hash_context,
50847e946e7SWyllys Ingersoll in_data, in_data_len);
50947e946e7SWyllys Ingersoll if (rc != CKR_OK) {
51047e946e7SWyllys Ingersoll goto error;
51147e946e7SWyllys Ingersoll }
51247e946e7SWyllys Ingersoll return (CKR_OK);
51347e946e7SWyllys Ingersoll error:
51447e946e7SWyllys Ingersoll (void) digest_mgr_cleanup(&context->hash_context);
51547e946e7SWyllys Ingersoll return (rc);
51647e946e7SWyllys Ingersoll }
51747e946e7SWyllys Ingersoll
51847e946e7SWyllys Ingersoll CK_RV
rsa_hash_pkcs_verify(SESSION * sess,SIGN_VERIFY_CONTEXT * ctx,CK_BYTE * in_data,CK_ULONG in_data_len,CK_BYTE * signature,CK_ULONG sig_len)51947e946e7SWyllys Ingersoll rsa_hash_pkcs_verify(SESSION * sess,
52047e946e7SWyllys Ingersoll SIGN_VERIFY_CONTEXT * ctx,
52147e946e7SWyllys Ingersoll CK_BYTE * in_data,
52247e946e7SWyllys Ingersoll CK_ULONG in_data_len,
52347e946e7SWyllys Ingersoll CK_BYTE * signature,
52447e946e7SWyllys Ingersoll CK_ULONG sig_len)
52547e946e7SWyllys Ingersoll {
52647e946e7SWyllys Ingersoll CK_BYTE * ber_data = NULL;
52747e946e7SWyllys Ingersoll CK_BYTE * octet_str = NULL;
52847e946e7SWyllys Ingersoll CK_BYTE * oid = NULL;
52947e946e7SWyllys Ingersoll CK_BYTE * tmp = NULL;
53047e946e7SWyllys Ingersoll
53147e946e7SWyllys Ingersoll CK_ULONG buf1[16];
53247e946e7SWyllys Ingersoll CK_BYTE hash[SHA1_DIGEST_LENGTH];
53347e946e7SWyllys Ingersoll DIGEST_CONTEXT digest_ctx;
53447e946e7SWyllys Ingersoll SIGN_VERIFY_CONTEXT verify_ctx;
53547e946e7SWyllys Ingersoll CK_MECHANISM digest_mech;
53647e946e7SWyllys Ingersoll CK_MECHANISM verify_mech;
53747e946e7SWyllys Ingersoll CK_ULONG ber_data_len, hash_len, octet_str_len, oid_len;
53847e946e7SWyllys Ingersoll CK_RV rc;
53947e946e7SWyllys Ingersoll
54047e946e7SWyllys Ingersoll if (! sess || ! ctx || ! in_data) {
54147e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED);
54247e946e7SWyllys Ingersoll }
54347e946e7SWyllys Ingersoll (void) memset(&digest_ctx, 0x0, sizeof (digest_ctx));
54447e946e7SWyllys Ingersoll (void) memset(&verify_ctx, 0x0, sizeof (verify_ctx));
54547e946e7SWyllys Ingersoll
54647e946e7SWyllys Ingersoll if (ctx->mech.mechanism == CKM_MD5_RSA_PKCS) {
54747e946e7SWyllys Ingersoll digest_mech.mechanism = CKM_MD5;
54847e946e7SWyllys Ingersoll oid = ber_AlgMd5;
54947e946e7SWyllys Ingersoll oid_len = ber_AlgMd5Len;
55047e946e7SWyllys Ingersoll hash_len = MD5_DIGEST_LENGTH;
55147e946e7SWyllys Ingersoll } else {
55247e946e7SWyllys Ingersoll digest_mech.mechanism = CKM_SHA_1;
55347e946e7SWyllys Ingersoll oid = ber_AlgSha1;
55447e946e7SWyllys Ingersoll oid_len = ber_AlgSha1Len;
55547e946e7SWyllys Ingersoll hash_len = SHA1_DIGEST_LENGTH;
55647e946e7SWyllys Ingersoll }
55747e946e7SWyllys Ingersoll
55847e946e7SWyllys Ingersoll digest_mech.ulParameterLen = 0;
55947e946e7SWyllys Ingersoll digest_mech.pParameter = NULL;
56047e946e7SWyllys Ingersoll
56147e946e7SWyllys Ingersoll rc = digest_mgr_init(sess, &digest_ctx, &digest_mech);
56247e946e7SWyllys Ingersoll if (rc != CKR_OK) {
56347e946e7SWyllys Ingersoll goto done;
56447e946e7SWyllys Ingersoll }
56547e946e7SWyllys Ingersoll rc = digest_mgr_digest(sess, FALSE, &digest_ctx, in_data,
56647e946e7SWyllys Ingersoll in_data_len, hash, &hash_len);
56747e946e7SWyllys Ingersoll if (rc != CKR_OK) {
56847e946e7SWyllys Ingersoll goto done;
56947e946e7SWyllys Ingersoll }
57047e946e7SWyllys Ingersoll rc = ber_encode_OCTET_STRING(FALSE, &octet_str, &octet_str_len,
57147e946e7SWyllys Ingersoll hash, hash_len);
57247e946e7SWyllys Ingersoll if (rc != CKR_OK)
57347e946e7SWyllys Ingersoll goto done;
57447e946e7SWyllys Ingersoll tmp = (CK_BYTE *)buf1;
57547e946e7SWyllys Ingersoll (void) memcpy(tmp, oid, oid_len);
57647e946e7SWyllys Ingersoll (void) memcpy(tmp + oid_len, octet_str, octet_str_len);
57747e946e7SWyllys Ingersoll
57847e946e7SWyllys Ingersoll rc = ber_encode_SEQUENCE(FALSE, &ber_data, &ber_data_len, tmp,
57947e946e7SWyllys Ingersoll (oid_len + octet_str_len));
58047e946e7SWyllys Ingersoll if (rc != CKR_OK) {
58147e946e7SWyllys Ingersoll goto done;
58247e946e7SWyllys Ingersoll }
58347e946e7SWyllys Ingersoll
58447e946e7SWyllys Ingersoll verify_mech.mechanism = CKM_RSA_PKCS;
58547e946e7SWyllys Ingersoll verify_mech.ulParameterLen = 0;
58647e946e7SWyllys Ingersoll verify_mech.pParameter = NULL;
58747e946e7SWyllys Ingersoll
58847e946e7SWyllys Ingersoll rc = verify_mgr_init(sess, &verify_ctx, &verify_mech, FALSE, ctx->key);
58947e946e7SWyllys Ingersoll if (rc != CKR_OK) {
59047e946e7SWyllys Ingersoll goto done;
59147e946e7SWyllys Ingersoll }
59247e946e7SWyllys Ingersoll rc = verify_mgr_verify(sess, &verify_ctx, ber_data,
59347e946e7SWyllys Ingersoll ber_data_len, signature, sig_len);
59447e946e7SWyllys Ingersoll done:
59547e946e7SWyllys Ingersoll if (octet_str) free(octet_str);
59647e946e7SWyllys Ingersoll if (ber_data) free(ber_data);
59747e946e7SWyllys Ingersoll
59847e946e7SWyllys Ingersoll (void) digest_mgr_cleanup(&digest_ctx);
59947e946e7SWyllys Ingersoll (void) sign_mgr_cleanup(&verify_ctx);
60047e946e7SWyllys Ingersoll return (rc);
60147e946e7SWyllys Ingersoll }
60247e946e7SWyllys Ingersoll
60347e946e7SWyllys Ingersoll CK_RV
rsa_hash_pkcs_verify_update(SESSION * sess,SIGN_VERIFY_CONTEXT * ctx,CK_BYTE * in_data,CK_ULONG in_data_len)60447e946e7SWyllys Ingersoll rsa_hash_pkcs_verify_update(SESSION * sess,
60547e946e7SWyllys Ingersoll SIGN_VERIFY_CONTEXT * ctx,
60647e946e7SWyllys Ingersoll CK_BYTE *in_data,
60747e946e7SWyllys Ingersoll CK_ULONG in_data_len)
60847e946e7SWyllys Ingersoll {
60947e946e7SWyllys Ingersoll RSA_DIGEST_CONTEXT * context = NULL;
61047e946e7SWyllys Ingersoll CK_MECHANISM digest_mech;
61147e946e7SWyllys Ingersoll CK_RV rc;
61247e946e7SWyllys Ingersoll
61347e946e7SWyllys Ingersoll if (! sess || ! ctx || ! in_data) {
61447e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED);
61547e946e7SWyllys Ingersoll }
61647e946e7SWyllys Ingersoll context = (RSA_DIGEST_CONTEXT *)ctx->context;
61747e946e7SWyllys Ingersoll
61847e946e7SWyllys Ingersoll if (context->flag == FALSE) {
61947e946e7SWyllys Ingersoll if (ctx->mech.mechanism == CKM_MD5_RSA_PKCS)
62047e946e7SWyllys Ingersoll digest_mech.mechanism = CKM_MD5;
62147e946e7SWyllys Ingersoll else
62247e946e7SWyllys Ingersoll digest_mech.mechanism = CKM_SHA_1;
62347e946e7SWyllys Ingersoll
62447e946e7SWyllys Ingersoll digest_mech.ulParameterLen = 0;
62547e946e7SWyllys Ingersoll digest_mech.pParameter = NULL;
62647e946e7SWyllys Ingersoll
62747e946e7SWyllys Ingersoll rc = digest_mgr_init(sess, &context->hash_context,
62847e946e7SWyllys Ingersoll &digest_mech);
62947e946e7SWyllys Ingersoll if (rc != CKR_OK)
63047e946e7SWyllys Ingersoll goto error;
63147e946e7SWyllys Ingersoll context->flag = TRUE;
63247e946e7SWyllys Ingersoll }
63347e946e7SWyllys Ingersoll
63447e946e7SWyllys Ingersoll rc = digest_mgr_digest_update(sess, &context->hash_context,
63547e946e7SWyllys Ingersoll in_data, in_data_len);
63647e946e7SWyllys Ingersoll if (rc != CKR_OK)
63747e946e7SWyllys Ingersoll goto error;
63847e946e7SWyllys Ingersoll return (CKR_OK);
63947e946e7SWyllys Ingersoll error:
64047e946e7SWyllys Ingersoll (void) digest_mgr_cleanup(&context->hash_context);
64147e946e7SWyllys Ingersoll return (rc);
64247e946e7SWyllys Ingersoll }
64347e946e7SWyllys Ingersoll
64447e946e7SWyllys Ingersoll CK_RV
rsa_hash_pkcs_sign_final(SESSION * sess,CK_BBOOL length_only,SIGN_VERIFY_CONTEXT * ctx,CK_BYTE * signature,CK_ULONG * sig_len)64547e946e7SWyllys Ingersoll rsa_hash_pkcs_sign_final(SESSION * sess,
64647e946e7SWyllys Ingersoll CK_BBOOL length_only,
64747e946e7SWyllys Ingersoll SIGN_VERIFY_CONTEXT * ctx,
64847e946e7SWyllys Ingersoll CK_BYTE * signature,
64947e946e7SWyllys Ingersoll CK_ULONG * sig_len)
65047e946e7SWyllys Ingersoll {
65147e946e7SWyllys Ingersoll CK_BYTE * ber_data = NULL;
65247e946e7SWyllys Ingersoll CK_BYTE * octet_str = NULL;
65347e946e7SWyllys Ingersoll CK_BYTE * oid = NULL;
65447e946e7SWyllys Ingersoll CK_BYTE * tmp = NULL;
65547e946e7SWyllys Ingersoll
65647e946e7SWyllys Ingersoll CK_ULONG buf1[16];
65747e946e7SWyllys Ingersoll CK_BYTE hash[SHA1_DIGEST_LENGTH];
65847e946e7SWyllys Ingersoll RSA_DIGEST_CONTEXT * context = NULL;
65947e946e7SWyllys Ingersoll CK_ULONG ber_data_len, hash_len, octet_str_len, oid_len;
66047e946e7SWyllys Ingersoll CK_MECHANISM sign_mech;
66147e946e7SWyllys Ingersoll SIGN_VERIFY_CONTEXT sign_ctx;
66247e946e7SWyllys Ingersoll CK_RV rc;
66347e946e7SWyllys Ingersoll
66447e946e7SWyllys Ingersoll if (! sess || ! ctx || ! sig_len) {
66547e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED);
66647e946e7SWyllys Ingersoll }
66747e946e7SWyllys Ingersoll
66847e946e7SWyllys Ingersoll if (ctx->mech.mechanism == CKM_MD5_RSA_PKCS) {
66947e946e7SWyllys Ingersoll oid = ber_AlgMd5;
67047e946e7SWyllys Ingersoll oid_len = ber_AlgMd5Len;
67147e946e7SWyllys Ingersoll hash_len = MD5_DIGEST_LENGTH;
67247e946e7SWyllys Ingersoll } else {
67347e946e7SWyllys Ingersoll oid = ber_AlgSha1;
67447e946e7SWyllys Ingersoll oid_len = ber_AlgSha1Len;
67547e946e7SWyllys Ingersoll hash_len = SHA1_DIGEST_LENGTH;
67647e946e7SWyllys Ingersoll }
67747e946e7SWyllys Ingersoll
67847e946e7SWyllys Ingersoll (void) memset(&sign_ctx, 0x0, sizeof (sign_ctx));
67947e946e7SWyllys Ingersoll
68047e946e7SWyllys Ingersoll context = (RSA_DIGEST_CONTEXT *)ctx->context;
68147e946e7SWyllys Ingersoll
68247e946e7SWyllys Ingersoll rc = digest_mgr_digest_final(sess,
68347e946e7SWyllys Ingersoll &context->hash_context, hash, &hash_len);
68447e946e7SWyllys Ingersoll if (rc != CKR_OK) {
68547e946e7SWyllys Ingersoll goto done;
68647e946e7SWyllys Ingersoll }
68747e946e7SWyllys Ingersoll
68847e946e7SWyllys Ingersoll rc = ber_encode_OCTET_STRING(FALSE, &octet_str, &octet_str_len,
68947e946e7SWyllys Ingersoll hash, hash_len);
69047e946e7SWyllys Ingersoll if (rc != CKR_OK) {
69147e946e7SWyllys Ingersoll goto done;
69247e946e7SWyllys Ingersoll }
69347e946e7SWyllys Ingersoll tmp = (CK_BYTE *)buf1;
69447e946e7SWyllys Ingersoll (void) memcpy(tmp, oid, oid_len);
69547e946e7SWyllys Ingersoll (void) memcpy(tmp + oid_len, octet_str, octet_str_len);
69647e946e7SWyllys Ingersoll
69747e946e7SWyllys Ingersoll rc = ber_encode_SEQUENCE(FALSE, &ber_data, &ber_data_len,
69847e946e7SWyllys Ingersoll tmp, (oid_len + octet_str_len));
69947e946e7SWyllys Ingersoll if (rc != CKR_OK) {
70047e946e7SWyllys Ingersoll goto done;
70147e946e7SWyllys Ingersoll }
70247e946e7SWyllys Ingersoll sign_mech.mechanism = CKM_RSA_PKCS;
70347e946e7SWyllys Ingersoll sign_mech.ulParameterLen = 0;
70447e946e7SWyllys Ingersoll sign_mech.pParameter = NULL;
70547e946e7SWyllys Ingersoll
70647e946e7SWyllys Ingersoll rc = sign_mgr_init(sess, &sign_ctx, &sign_mech, FALSE, ctx->key);
70747e946e7SWyllys Ingersoll if (rc != CKR_OK) {
70847e946e7SWyllys Ingersoll goto done;
70947e946e7SWyllys Ingersoll }
71047e946e7SWyllys Ingersoll rc = sign_mgr_sign(sess, length_only, &sign_ctx, ber_data,
71147e946e7SWyllys Ingersoll ber_data_len, signature, sig_len);
71247e946e7SWyllys Ingersoll
71347e946e7SWyllys Ingersoll if (length_only == TRUE || rc == CKR_BUFFER_TOO_SMALL) {
71447e946e7SWyllys Ingersoll (void) sign_mgr_cleanup(&sign_ctx);
71547e946e7SWyllys Ingersoll return (rc);
71647e946e7SWyllys Ingersoll }
71747e946e7SWyllys Ingersoll
71847e946e7SWyllys Ingersoll done:
71947e946e7SWyllys Ingersoll if (octet_str) free(octet_str);
72047e946e7SWyllys Ingersoll if (ber_data) free(ber_data);
72147e946e7SWyllys Ingersoll
72247e946e7SWyllys Ingersoll (void) digest_mgr_cleanup(&context->hash_context);
72347e946e7SWyllys Ingersoll (void) sign_mgr_cleanup(&sign_ctx);
72447e946e7SWyllys Ingersoll return (rc);
72547e946e7SWyllys Ingersoll }
72647e946e7SWyllys Ingersoll
72747e946e7SWyllys Ingersoll CK_RV
rsa_hash_pkcs_verify_final(SESSION * sess,SIGN_VERIFY_CONTEXT * ctx,CK_BYTE * signature,CK_ULONG sig_len)72847e946e7SWyllys Ingersoll rsa_hash_pkcs_verify_final(SESSION * sess,
72947e946e7SWyllys Ingersoll SIGN_VERIFY_CONTEXT * ctx,
73047e946e7SWyllys Ingersoll CK_BYTE * signature,
73147e946e7SWyllys Ingersoll CK_ULONG sig_len)
73247e946e7SWyllys Ingersoll {
73347e946e7SWyllys Ingersoll CK_BYTE * ber_data = NULL;
73447e946e7SWyllys Ingersoll CK_BYTE * octet_str = NULL;
73547e946e7SWyllys Ingersoll CK_BYTE * oid = NULL;
73647e946e7SWyllys Ingersoll CK_BYTE * tmp = NULL;
73747e946e7SWyllys Ingersoll
73847e946e7SWyllys Ingersoll CK_ULONG buf1[16];
73947e946e7SWyllys Ingersoll CK_BYTE hash[SHA1_DIGEST_LENGTH];
74047e946e7SWyllys Ingersoll RSA_DIGEST_CONTEXT * context = NULL;
74147e946e7SWyllys Ingersoll CK_ULONG ber_data_len, hash_len, octet_str_len, oid_len;
74247e946e7SWyllys Ingersoll CK_MECHANISM verify_mech;
74347e946e7SWyllys Ingersoll SIGN_VERIFY_CONTEXT verify_ctx;
74447e946e7SWyllys Ingersoll CK_RV rc;
74547e946e7SWyllys Ingersoll
74647e946e7SWyllys Ingersoll if (! sess || ! ctx || ! signature) {
74747e946e7SWyllys Ingersoll return (CKR_FUNCTION_FAILED);
74847e946e7SWyllys Ingersoll }
74947e946e7SWyllys Ingersoll if (ctx->mech.mechanism == CKM_MD5_RSA_PKCS) {
75047e946e7SWyllys Ingersoll oid = ber_AlgMd5;
75147e946e7SWyllys Ingersoll oid_len = ber_AlgMd5Len;
75247e946e7SWyllys Ingersoll hash_len = MD5_DIGEST_LENGTH;
75347e946e7SWyllys Ingersoll } else {
75447e946e7SWyllys Ingersoll oid = ber_AlgSha1;
75547e946e7SWyllys Ingersoll oid_len = ber_AlgSha1Len;
75647e946e7SWyllys Ingersoll hash_len = SHA1_DIGEST_LENGTH;
75747e946e7SWyllys Ingersoll }
75847e946e7SWyllys Ingersoll
75947e946e7SWyllys Ingersoll (void) memset(&verify_ctx, 0x0, sizeof (verify_ctx));
76047e946e7SWyllys Ingersoll
76147e946e7SWyllys Ingersoll context = (RSA_DIGEST_CONTEXT *)ctx->context;
76247e946e7SWyllys Ingersoll
76347e946e7SWyllys Ingersoll rc = digest_mgr_digest_final(sess, &context->hash_context,
76447e946e7SWyllys Ingersoll hash, &hash_len);
76547e946e7SWyllys Ingersoll if (rc != CKR_OK) {
76647e946e7SWyllys Ingersoll goto done;
76747e946e7SWyllys Ingersoll }
76847e946e7SWyllys Ingersoll rc = ber_encode_OCTET_STRING(FALSE, &octet_str, &octet_str_len,
76947e946e7SWyllys Ingersoll hash, hash_len);
77047e946e7SWyllys Ingersoll if (rc != CKR_OK) {
77147e946e7SWyllys Ingersoll goto done;
77247e946e7SWyllys Ingersoll }
77347e946e7SWyllys Ingersoll tmp = (CK_BYTE *)buf1;
77447e946e7SWyllys Ingersoll (void) memcpy(tmp, oid, oid_len);
77547e946e7SWyllys Ingersoll (void) memcpy(tmp + oid_len, octet_str, octet_str_len);
77647e946e7SWyllys Ingersoll
77747e946e7SWyllys Ingersoll rc = ber_encode_SEQUENCE(FALSE, &ber_data, &ber_data_len,
77847e946e7SWyllys Ingersoll tmp, (oid_len + octet_str_len));
77947e946e7SWyllys Ingersoll if (rc != CKR_OK) {
78047e946e7SWyllys Ingersoll goto done;
78147e946e7SWyllys Ingersoll }
78247e946e7SWyllys Ingersoll verify_mech.mechanism = CKM_RSA_PKCS;
78347e946e7SWyllys Ingersoll verify_mech.ulParameterLen = 0;
78447e946e7SWyllys Ingersoll verify_mech.pParameter = NULL;
78547e946e7SWyllys Ingersoll
78647e946e7SWyllys Ingersoll rc = verify_mgr_init(sess, &verify_ctx, &verify_mech, FALSE, ctx->key);
78747e946e7SWyllys Ingersoll if (rc != CKR_OK) {
78847e946e7SWyllys Ingersoll goto done;
78947e946e7SWyllys Ingersoll }
79047e946e7SWyllys Ingersoll rc = verify_mgr_verify(sess, &verify_ctx, ber_data,
79147e946e7SWyllys Ingersoll ber_data_len, signature, sig_len);
79247e946e7SWyllys Ingersoll done:
79347e946e7SWyllys Ingersoll if (octet_str) free(octet_str);
79447e946e7SWyllys Ingersoll if (ber_data) free(ber_data);
79547e946e7SWyllys Ingersoll (void) digest_mgr_cleanup(&context->hash_context);
79647e946e7SWyllys Ingersoll (void) verify_mgr_cleanup(&verify_ctx);
79747e946e7SWyllys Ingersoll return (rc);
79847e946e7SWyllys Ingersoll }
799