1 /* 2 * The Initial Developer of the Original Code is International 3 * Business Machines Corporation. Portions created by IBM 4 * Corporation are Copyright (C) 2005 International Business 5 * Machines Corporation. All Rights Reserved. 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 /* (C) COPYRIGHT International Business Machines Corp. 2001, 2002, 2005 */ 23 /* 24 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 25 * Use is subject to license terms. 26 */ 27 28 #include "tpmtok_int.h" 29 30 CK_RV 31 verify_mgr_init(SESSION * sess, 32 SIGN_VERIFY_CONTEXT * ctx, 33 CK_MECHANISM * mech, 34 CK_BBOOL recover_mode, 35 CK_OBJECT_HANDLE key) 36 { 37 OBJECT * key_obj = NULL; 38 CK_ATTRIBUTE * attr = NULL; 39 CK_KEY_TYPE keytype; 40 CK_OBJECT_CLASS class; 41 CK_BBOOL flag; 42 CK_RV rc; 43 44 45 if (! sess || ! ctx) { 46 return (CKR_FUNCTION_FAILED); 47 } 48 if (ctx->active != FALSE) { 49 return (CKR_OPERATION_ACTIVE); 50 } 51 52 // key usage restrictions 53 // 54 rc = object_mgr_find_in_map1(sess->hContext, key, &key_obj); 55 if (rc != CKR_OK) { 56 return (CKR_KEY_HANDLE_INVALID); 57 } 58 // is key allowed to verify signatures? 59 // 60 rc = template_attribute_find(key_obj->template, CKA_VERIFY, &attr); 61 if (rc == FALSE) { 62 return (CKR_KEY_TYPE_INCONSISTENT); 63 } else { 64 flag = *(CK_BBOOL *)attr->pValue; 65 if (flag != TRUE) { 66 return (CKR_KEY_FUNCTION_NOT_PERMITTED); 67 } 68 } 69 70 switch (mech->mechanism) { 71 case CKM_RSA_PKCS: 72 { 73 rc = template_attribute_find(key_obj->template, 74 CKA_KEY_TYPE, &attr); 75 if (rc == FALSE) { 76 return (CKR_KEY_TYPE_INCONSISTENT); 77 } else { 78 keytype = *(CK_KEY_TYPE *)attr->pValue; 79 if (keytype != CKK_RSA) { 80 return (CKR_KEY_TYPE_INCONSISTENT); 81 } 82 } 83 84 flag = template_attribute_find(key_obj->template, 85 CKA_CLASS, &attr); 86 if (flag == FALSE) { 87 return (CKR_FUNCTION_FAILED); 88 } 89 else 90 class = *(CK_OBJECT_CLASS *)attr->pValue; 91 92 if (class != CKO_PUBLIC_KEY) { 93 return (CKR_FUNCTION_FAILED); 94 } 95 // PKCS #11 doesn't allow multi - part RSA operations 96 ctx->context_len = 0; 97 ctx->context = NULL; 98 } 99 break; 100 101 case CKM_MD5_RSA_PKCS: 102 case CKM_SHA1_RSA_PKCS: 103 { 104 rc = template_attribute_find(key_obj->template, 105 CKA_KEY_TYPE, &attr); 106 if (rc == FALSE) { 107 return (CKR_KEY_TYPE_INCONSISTENT); 108 } else { 109 keytype = *(CK_KEY_TYPE *)attr->pValue; 110 if (keytype != CKK_RSA) { 111 return (CKR_KEY_TYPE_INCONSISTENT); 112 } 113 } 114 115 flag = template_attribute_find(key_obj->template, 116 CKA_CLASS, &attr); 117 if (flag == FALSE) { 118 return (CKR_FUNCTION_FAILED); 119 } 120 else 121 class = *(CK_OBJECT_CLASS *)attr->pValue; 122 123 if (class != CKO_PUBLIC_KEY) { 124 return (CKR_FUNCTION_FAILED); 125 } 126 ctx->context_len = sizeof (RSA_DIGEST_CONTEXT); 127 ctx->context = (CK_BYTE *)malloc( 128 sizeof (RSA_DIGEST_CONTEXT)); 129 if (! ctx->context) { 130 return (CKR_HOST_MEMORY); 131 } 132 (void) memset(ctx->context, 0x0, 133 sizeof (RSA_DIGEST_CONTEXT)); 134 } 135 break; 136 137 case CKM_MD5_HMAC: 138 case CKM_SHA_1_HMAC: 139 { 140 rc = template_attribute_find(key_obj->template, 141 CKA_KEY_TYPE, &attr); 142 if (rc == FALSE) { 143 return (CKR_KEY_TYPE_INCONSISTENT); 144 } else { 145 keytype = *(CK_KEY_TYPE *)attr->pValue; 146 if (keytype != CKK_GENERIC_SECRET) { 147 return (CKR_KEY_TYPE_INCONSISTENT); 148 } 149 } 150 151 // PKCS #11 doesn't allow multi - part HMAC operations 152 ctx->context_len = 0; 153 ctx->context = NULL; 154 } 155 break; 156 157 case CKM_MD5_HMAC_GENERAL: 158 case CKM_SHA_1_HMAC_GENERAL: 159 { 160 CK_MAC_GENERAL_PARAMS *param = 161 (CK_MAC_GENERAL_PARAMS *)mech->pParameter; 162 163 if (mech->ulParameterLen != 164 sizeof (CK_MAC_GENERAL_PARAMS)) { 165 return (CKR_MECHANISM_PARAM_INVALID); 166 } 167 if ((mech->mechanism == CKM_MD5_HMAC_GENERAL) && 168 (*param > 16)) { 169 return (CKR_MECHANISM_PARAM_INVALID); 170 } 171 if ((mech->mechanism == CKM_SHA_1_HMAC_GENERAL) && 172 (*param > 20)) { 173 return (CKR_MECHANISM_PARAM_INVALID); 174 } 175 rc = template_attribute_find(key_obj->template, 176 CKA_KEY_TYPE, &attr); 177 if (rc == FALSE) { 178 return (CKR_KEY_TYPE_INCONSISTENT); 179 } else { 180 keytype = *(CK_KEY_TYPE *)attr->pValue; 181 if (keytype != CKK_GENERIC_SECRET) { 182 return (CKR_KEY_TYPE_INCONSISTENT); 183 } 184 } 185 186 ctx->context_len = 0; 187 ctx->context = NULL; 188 } 189 break; 190 191 default: 192 return (CKR_MECHANISM_INVALID); 193 } 194 195 196 ctx->key = key; 197 ctx->mech.ulParameterLen = mech->ulParameterLen; 198 ctx->mech.mechanism = mech->mechanism; 199 ctx->mech.pParameter = mech->pParameter; 200 ctx->multi = FALSE; 201 ctx->active = TRUE; 202 ctx->recover = recover_mode; 203 204 return (CKR_OK); 205 } 206 207 CK_RV 208 verify_mgr_cleanup(SIGN_VERIFY_CONTEXT *ctx) 209 { 210 if (! ctx) { 211 return (CKR_FUNCTION_FAILED); 212 } 213 ctx->key = 0; 214 ctx->mech.ulParameterLen = 0; 215 ctx->mech.mechanism = 0; 216 ctx->multi = FALSE; 217 ctx->active = FALSE; 218 ctx->recover = FALSE; 219 ctx->context_len = 0; 220 ctx->mech.pParameter = NULL; 221 222 if (ctx->context) { 223 free(ctx->context); 224 ctx->context = NULL; 225 } 226 227 return (CKR_OK); 228 } 229 230 CK_RV 231 verify_mgr_verify(SESSION * sess, 232 SIGN_VERIFY_CONTEXT * ctx, 233 CK_BYTE * in_data, 234 CK_ULONG in_data_len, 235 CK_BYTE * signature, 236 CK_ULONG sig_len) 237 { 238 if (! sess || ! ctx) { 239 return (CKR_FUNCTION_FAILED); 240 } 241 if (ctx->active == FALSE) { 242 return (CKR_OPERATION_NOT_INITIALIZED); 243 } 244 if (ctx->recover == TRUE) { 245 return (CKR_OPERATION_NOT_INITIALIZED); 246 } 247 248 if (! in_data || ! signature) { 249 return (CKR_FUNCTION_FAILED); 250 } 251 if (ctx->multi == TRUE) { 252 return (CKR_OPERATION_ACTIVE); 253 } 254 255 switch (ctx->mech.mechanism) { 256 case CKM_RSA_PKCS: 257 return (rsa_pkcs_verify(sess, ctx, 258 in_data, in_data_len, 259 signature, sig_len)); 260 case CKM_MD5_RSA_PKCS: 261 case CKM_SHA1_RSA_PKCS: 262 return (rsa_hash_pkcs_verify(sess, ctx, 263 in_data, in_data_len, 264 signature, sig_len)); 265 266 case CKM_MD5_HMAC: 267 case CKM_MD5_HMAC_GENERAL: 268 return (md5_hmac_verify(sess, ctx, 269 in_data, in_data_len, 270 signature, sig_len)); 271 case CKM_SHA_1_HMAC: 272 case CKM_SHA_1_HMAC_GENERAL: 273 return (sha1_hmac_verify(sess, ctx, 274 in_data, in_data_len, 275 signature, sig_len)); 276 default: 277 return (CKR_MECHANISM_INVALID); 278 } 279 } 280 281 CK_RV 282 verify_mgr_verify_update(SESSION * sess, 283 SIGN_VERIFY_CONTEXT * ctx, 284 CK_BYTE * in_data, 285 CK_ULONG in_data_len) 286 { 287 if (! sess || ! ctx || ! in_data) { 288 return (CKR_FUNCTION_FAILED); 289 } 290 if (ctx->active == FALSE) { 291 return (CKR_OPERATION_NOT_INITIALIZED); 292 } 293 if (ctx->recover == TRUE) { 294 return (CKR_OPERATION_NOT_INITIALIZED); 295 } 296 ctx->multi = TRUE; 297 298 299 switch (ctx->mech.mechanism) { 300 case CKM_MD5_RSA_PKCS: 301 case CKM_SHA1_RSA_PKCS: 302 return (rsa_hash_pkcs_verify_update(sess, ctx, 303 in_data, in_data_len)); 304 default: 305 return (CKR_MECHANISM_INVALID); 306 } 307 } 308 309 CK_RV 310 verify_mgr_verify_final(SESSION * sess, 311 SIGN_VERIFY_CONTEXT * ctx, 312 CK_BYTE * signature, 313 CK_ULONG sig_len) 314 { 315 if (! sess || ! ctx) { 316 return (CKR_FUNCTION_FAILED); 317 } 318 if (ctx->active == FALSE) { 319 return (CKR_OPERATION_NOT_INITIALIZED); 320 } 321 if (ctx->recover == TRUE) { 322 return (CKR_OPERATION_NOT_INITIALIZED); 323 } 324 switch (ctx->mech.mechanism) { 325 case CKM_MD5_RSA_PKCS: 326 case CKM_SHA1_RSA_PKCS: 327 return (rsa_hash_pkcs_verify_final(sess, ctx, 328 signature, sig_len)); 329 default: 330 return (CKR_MECHANISM_INVALID); 331 } 332 } 333 334 CK_RV 335 verify_mgr_verify_recover(SESSION * sess, 336 CK_BBOOL length_only, 337 SIGN_VERIFY_CONTEXT * ctx, 338 CK_BYTE * signature, 339 CK_ULONG sig_len, 340 CK_BYTE * out_data, 341 CK_ULONG * out_len) 342 { 343 if (! sess || ! ctx) { 344 return (CKR_FUNCTION_FAILED); 345 } 346 if (ctx->active == FALSE) { 347 return (CKR_OPERATION_NOT_INITIALIZED); 348 } 349 if (ctx->recover == FALSE) { 350 return (CKR_OPERATION_NOT_INITIALIZED); 351 } 352 353 if (! signature || ! out_len) { 354 return (CKR_FUNCTION_FAILED); 355 } 356 if (ctx->multi == TRUE) { 357 return (CKR_OPERATION_ACTIVE); 358 } 359 360 switch (ctx->mech.mechanism) { 361 case CKM_RSA_PKCS: 362 return (rsa_pkcs_verify_recover(sess, length_only, 363 ctx, signature, sig_len, out_data, out_len)); 364 default: 365 return (CKR_MECHANISM_INVALID); 366 } 367 } 368