1 /*
2  * p11test_case_mechs.c: Check mechanisms supported by token
3  *
4  * Copyright (C) 2016, 2017 Red Hat, Inc.
5  *
6  * Author: Jakub Jelen <jjelen@redhat.com>
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20  */
21 
22 #include "p11test_case_mechs.h"
23 
supported_mechanisms_test(void ** state)24 void supported_mechanisms_test(void **state) {
25 	token_info_t *info = (token_info_t *) *state;
26 	CK_FUNCTION_LIST_PTR function_pointer = info->function_pointer;
27 
28 	CK_RV rv;
29 	CK_ULONG mechanism_count, i;
30 	CK_MECHANISM_TYPE_PTR mechanism_list;
31 	CK_MECHANISM_INFO_PTR mechanism_info;
32 	CK_FLAGS j;
33 	test_mech_t *mech = NULL;
34 
35 	P11TEST_START(info);
36 	rv = function_pointer->C_GetMechanismList(info->slot_id, NULL_PTR,
37 		&mechanism_count);
38 	if ((rv == CKR_OK) && (mechanism_count > 0)) {
39 		mechanism_list = (CK_MECHANISM_TYPE_PTR)
40 			malloc(mechanism_count * sizeof(CK_MECHANISM_TYPE));
41 		rv = function_pointer->C_GetMechanismList(info->slot_id,
42 			mechanism_list, &mechanism_count);
43 		if (rv != CKR_OK) {
44 			free(mechanism_list);
45 			function_pointer->C_Finalize(NULL_PTR);
46 			P11TEST_FAIL(info, "Could not get mechanism list!");
47 		}
48 
49 		mechanism_info = (CK_MECHANISM_INFO_PTR)
50 			malloc(mechanism_count * sizeof(CK_MECHANISM_INFO));
51 		if (mechanism_info == NULL)
52 			P11TEST_FAIL(info, "Couldn't malloc()");
53 
54 		for (i = 0; i < mechanism_count; i++) {
55 			CK_MECHANISM_TYPE mechanism_type = mechanism_list[i];
56 			rv = function_pointer->C_GetMechanismInfo(info->slot_id,
57 				mechanism_type, &mechanism_info[i]);
58 			if (rv != CKR_OK)
59 				continue;
60 
61 			/* store mechanisms list for later tests */
62 
63 			/* List all known RSA mechanisms */
64 			if (mechanism_list[i] == CKM_RSA_X_509
65 					|| mechanism_list[i] == CKM_RSA_PKCS
66 					|| mechanism_list[i] == CKM_MD5_RSA_PKCS
67 					|| mechanism_list[i] == CKM_RIPEMD160_RSA_PKCS
68 					|| mechanism_list[i] == CKM_SHA1_RSA_PKCS
69 					|| mechanism_list[i] == CKM_SHA224_RSA_PKCS
70 					|| mechanism_list[i] == CKM_SHA256_RSA_PKCS
71 					|| mechanism_list[i] == CKM_SHA384_RSA_PKCS
72 					|| mechanism_list[i] == CKM_SHA512_RSA_PKCS
73 					|| mechanism_list[i] == CKM_RSA_PKCS_PSS
74 					|| mechanism_list[i] == CKM_SHA1_RSA_PKCS_PSS
75 					|| mechanism_list[i] == CKM_SHA256_RSA_PKCS_PSS
76 					|| mechanism_list[i] == CKM_SHA384_RSA_PKCS_PSS
77 					|| mechanism_list[i] == CKM_SHA512_RSA_PKCS_PSS
78 					|| mechanism_list[i] == CKM_RSA_PKCS_OAEP) {
79 				if (token.num_rsa_mechs < MAX_MECHS) {
80 					mech = &token.rsa_mechs[token.num_rsa_mechs++];
81 					mech->mech = mechanism_list[i];
82 					mech->usage_flags = mechanism_info[i].flags;
83 				} else
84 					P11TEST_FAIL(info, "Too many RSA mechanisms (%d)", MAX_MECHS);
85 			}
86 
87 			/* We list all known EC mechanisms */
88 			if (mechanism_list[i] == CKM_ECDSA
89 					|| mechanism_list[i] == CKM_ECDSA_SHA1
90 					|| mechanism_list[i] == CKM_ECDSA_SHA256
91 					|| mechanism_list[i] == CKM_ECDSA_SHA384
92 					|| mechanism_list[i] == CKM_ECDSA_SHA512
93 					/* Including derive mechanisms */
94 					|| mechanism_list[i] == CKM_ECDH1_DERIVE
95 					|| mechanism_list[i] == CKM_ECDH1_COFACTOR_DERIVE
96 					|| mechanism_list[i] == CKM_ECMQV_DERIVE) {
97 				if (token.num_ec_mechs < MAX_MECHS) {
98 					mech = &token.ec_mechs[token.num_ec_mechs++];
99 					mech->mech = mechanism_list[i];
100 					mech->usage_flags = mechanism_info[i].flags;
101 				} else
102 					P11TEST_FAIL(info, "Too many EC mechanisms (%d)", MAX_MECHS);
103 			}
104 
105 			/* We list all known edwards EC curve mechanisms */
106 			if (mechanism_list[i] == CKM_EDDSA) {
107 				if (token.num_ed_mechs < MAX_MECHS) {
108 					mech = &token.ed_mechs[token.num_ed_mechs++];
109 					mech->mech = mechanism_list[i];
110 					mech->usage_flags = mechanism_info[i].flags;
111 				} else
112 					P11TEST_FAIL(info, "Too many edwards EC mechanisms (%d)", MAX_MECHS);
113 			}
114 
115 			/* We list all known montgomery EC curve mechanisms */
116 			if (mechanism_list[i] == CKM_XEDDSA
117 					|| mechanism_list[i] == CKM_ECDH1_DERIVE) {
118 				if (token.num_montgomery_mechs < MAX_MECHS) {
119 					mech = &token.montgomery_mechs[token.num_montgomery_mechs++];
120 					mech->mech = mechanism_list[i];
121 					mech->usage_flags = mechanism_info[i].flags;
122 				} else
123 					P11TEST_FAIL(info, "Too many montgomery EC mechanisms (%d)", MAX_MECHS);
124 			}
125 
126 			if ((mechanism_info[i].flags & CKF_GENERATE_KEY_PAIR) != 0) {
127 				if (token.num_keygen_mechs < MAX_MECHS) {
128 					mech = &token.keygen_mechs[token.num_keygen_mechs++];
129 					mech->mech = mechanism_list[i];
130 					mech->usage_flags = mechanism_info[i].flags;
131 				} else
132 					P11TEST_FAIL(info, "Too many KEYGEN mechanisms (%d)", MAX_MECHS);
133 			}
134 		}
135 
136 		printf("[      MECHANISM      ] [ KEY SIZE ] [  FLAGS   ]\n");
137 		printf("[        CKM_*        ] [ MIN][ MAX] [          ]\n");
138 		P11TEST_DATA_ROW(info, 4,
139 			's', "MECHANISM",
140 			's', "MIN KEY",
141 			's', "MAX KEY",
142 			's', "FLAGS");
143 		for (i = 0; i < mechanism_count; i++) {
144 			printf("[%-21s] [%4lu][%4lu] [%10s]",
145 				get_mechanism_name(mechanism_list[i]),
146 				mechanism_info[i].ulMinKeySize,
147 				mechanism_info[i].ulMaxKeySize,
148 				get_mechanism_flag_name(mechanism_info[i].flags));
149 			P11TEST_DATA_ROW(info, 4,
150 				's', get_mechanism_name(mechanism_list[i]),
151 				'd', mechanism_info[i].ulMinKeySize,
152 				'd', mechanism_info[i].ulMaxKeySize,
153 				's', get_mechanism_flag_name(mechanism_info[i].flags));
154 			for (j = 1; j <= CKF_EC_COMPRESS; j = j<<1)
155 				if ((mechanism_info[i].flags & j) != 0)
156 					printf(" %s", get_mechanism_flag_name(j));
157 			printf("\n");
158 		}
159 		free(mechanism_list);
160 		free(mechanism_info);
161 	}
162 	P11TEST_PASS(info);
163 }
164 
165