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