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 sign_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 rc = object_mgr_find_in_map1(sess->hContext, key, &key_obj); 54 if (rc != CKR_OK) { 55 return (CKR_KEY_HANDLE_INVALID); 56 } 57 rc = template_attribute_find(key_obj->template, CKA_SIGN, &attr); 58 if (rc == FALSE) { 59 return (CKR_KEY_TYPE_INCONSISTENT); 60 } else { 61 flag = *(CK_BBOOL *)attr->pValue; 62 if (flag != TRUE) { 63 return (CKR_KEY_FUNCTION_NOT_PERMITTED); 64 } 65 } 66 67 switch (mech->mechanism) { 68 case CKM_RSA_PKCS: 69 { 70 if (mech->ulParameterLen != 0) { 71 return (CKR_MECHANISM_PARAM_INVALID); 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 // must be a PRIVATE key 85 // 86 flag = template_attribute_find(key_obj->template, 87 CKA_CLASS, &attr); 88 if (flag == FALSE) { 89 return (CKR_KEY_TYPE_INCONSISTENT); 90 } 91 else 92 class = *(CK_OBJECT_CLASS *)attr->pValue; 93 94 if (class != CKO_PRIVATE_KEY) { 95 return (CKR_KEY_TYPE_INCONSISTENT); 96 } 97 // PKCS #11 doesn't allow multi - part RSA operations 98 // 99 ctx->context_len = 0; 100 ctx->context = NULL; 101 } 102 break; 103 case CKM_MD5_RSA_PKCS: 104 case CKM_SHA1_RSA_PKCS: 105 { 106 if (mech->ulParameterLen != 0) { 107 return (CKR_MECHANISM_PARAM_INVALID); 108 } 109 rc = template_attribute_find(key_obj->template, 110 CKA_KEY_TYPE, &attr); 111 if (rc == FALSE) { 112 return (CKR_KEY_TYPE_INCONSISTENT); 113 } else { 114 keytype = *(CK_KEY_TYPE *)attr->pValue; 115 if (keytype != CKK_RSA) { 116 return (CKR_KEY_TYPE_INCONSISTENT); 117 } 118 } 119 120 // must be a PRIVATE key operation 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_PRIVATE_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 case CKM_MD5_HMAC: 144 case CKM_SHA_1_HMAC: 145 { 146 if (mech->ulParameterLen != 0) { 147 return (CKR_MECHANISM_PARAM_INVALID); 148 } 149 rc = template_attribute_find(key_obj->template, 150 CKA_KEY_TYPE, &attr); 151 if (rc == FALSE) { 152 return (CKR_KEY_TYPE_INCONSISTENT); 153 } else { 154 keytype = *(CK_KEY_TYPE *)attr->pValue; 155 if (keytype != CKK_GENERIC_SECRET) { 156 return (CKR_KEY_TYPE_INCONSISTENT); 157 } 158 } 159 160 // PKCS #11 doesn't allow multi - part HMAC operations 161 // 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 178 if ((mech->mechanism == CKM_MD5_HMAC_GENERAL) && 179 (*param > 16)) { 180 return (CKR_MECHANISM_PARAM_INVALID); 181 } 182 if ((mech->mechanism == CKM_SHA_1_HMAC_GENERAL) && 183 (*param > 20)) { 184 return (CKR_MECHANISM_PARAM_INVALID); 185 } 186 rc = template_attribute_find(key_obj->template, 187 CKA_KEY_TYPE, &attr); 188 if (rc == FALSE) { 189 return (CKR_KEY_TYPE_INCONSISTENT); 190 } else { 191 keytype = *(CK_KEY_TYPE *)attr->pValue; 192 if (keytype != CKK_GENERIC_SECRET) { 193 return (CKR_KEY_TYPE_INCONSISTENT); 194 } 195 } 196 197 // PKCS #11 doesn't allow multi - part HMAC operations 198 // 199 ctx->context_len = 0; 200 ctx->context = NULL; 201 } 202 break; 203 default: 204 return (CKR_MECHANISM_INVALID); 205 } 206 207 208 if (mech->ulParameterLen > 0) { 209 ptr = (CK_BYTE *)malloc(mech->ulParameterLen); 210 if (! ptr) { 211 return (CKR_HOST_MEMORY); 212 } 213 (void) memcpy(ptr, mech->pParameter, mech->ulParameterLen); 214 } 215 216 ctx->key = key; 217 ctx->mech.ulParameterLen = mech->ulParameterLen; 218 ctx->mech.mechanism = mech->mechanism; 219 ctx->mech.pParameter = ptr; 220 ctx->multi = FALSE; 221 ctx->active = TRUE; 222 ctx->recover = recover_mode; 223 224 return (CKR_OK); 225 } 226 227 CK_RV 228 sign_mgr_cleanup(SIGN_VERIFY_CONTEXT *ctx) 229 { 230 if (! ctx) { 231 return (CKR_FUNCTION_FAILED); 232 } 233 ctx->key = 0; 234 ctx->mech.ulParameterLen = 0; 235 ctx->mech.mechanism = 0; 236 ctx->multi = FALSE; 237 ctx->active = FALSE; 238 ctx->recover = FALSE; 239 ctx->context_len = 0; 240 241 if (ctx->mech.pParameter) { 242 free(ctx->mech.pParameter); 243 ctx->mech.pParameter = NULL; 244 } 245 246 if (ctx->context) { 247 free(ctx->context); 248 ctx->context = NULL; 249 } 250 251 return (CKR_OK); 252 } 253 254 CK_RV 255 sign_mgr_sign(SESSION * sess, 256 CK_BBOOL length_only, 257 SIGN_VERIFY_CONTEXT * ctx, 258 CK_BYTE * in_data, 259 CK_ULONG in_data_len, 260 CK_BYTE * out_data, 261 CK_ULONG * out_data_len) 262 { 263 if (! sess || ! ctx) { 264 return (CKR_FUNCTION_FAILED); 265 } 266 if (ctx->active == FALSE) { 267 return (CKR_OPERATION_NOT_INITIALIZED); 268 } 269 if (ctx->recover == TRUE) { 270 return (CKR_OPERATION_NOT_INITIALIZED); 271 } 272 273 // if the caller just wants the signature length, there is no reason to 274 // specify the input data. I just need the input data length 275 // 276 if ((length_only == FALSE) && (! in_data || ! out_data)) { 277 return (CKR_FUNCTION_FAILED); 278 } 279 if (ctx->multi == TRUE) { 280 return (CKR_OPERATION_ACTIVE); 281 } 282 switch (ctx->mech.mechanism) { 283 case CKM_RSA_PKCS: 284 return (rsa_pkcs_sign(sess, length_only, ctx, 285 in_data, in_data_len, 286 out_data, out_data_len)); 287 case CKM_MD5_RSA_PKCS: 288 case CKM_SHA1_RSA_PKCS: 289 return (rsa_hash_pkcs_sign(sess, length_only, ctx, 290 in_data, in_data_len, 291 out_data, out_data_len)); 292 293 case CKM_MD5_HMAC: 294 case CKM_MD5_HMAC_GENERAL: 295 return (md5_hmac_sign(sess, length_only, ctx, 296 in_data, in_data_len, 297 out_data, out_data_len)); 298 case CKM_SHA_1_HMAC: 299 case CKM_SHA_1_HMAC_GENERAL: 300 return (sha1_hmac_sign(sess, length_only, ctx, 301 in_data, in_data_len, 302 out_data, out_data_len)); 303 default: 304 return (CKR_MECHANISM_INVALID); 305 } 306 } 307 308 CK_RV 309 sign_mgr_sign_update(SESSION * sess, 310 SIGN_VERIFY_CONTEXT * ctx, 311 CK_BYTE * in_data, 312 CK_ULONG in_data_len) 313 { 314 if (! sess || ! ctx || ! in_data) { 315 return (CKR_FUNCTION_FAILED); 316 } 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 ctx->multi = TRUE; 325 326 switch (ctx->mech.mechanism) { 327 case CKM_MD5_RSA_PKCS: 328 case CKM_SHA1_RSA_PKCS: 329 return (rsa_hash_pkcs_sign_update(sess, ctx, 330 in_data, in_data_len)); 331 default: 332 return (CKR_MECHANISM_INVALID); 333 } 334 } 335 336 CK_RV 337 sign_mgr_sign_final(SESSION * sess, 338 CK_BBOOL length_only, 339 SIGN_VERIFY_CONTEXT * ctx, 340 CK_BYTE * signature, 341 CK_ULONG * sig_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 == TRUE) { 350 return (CKR_OPERATION_NOT_INITIALIZED); 351 } 352 switch (ctx->mech.mechanism) { 353 case CKM_MD5_RSA_PKCS: 354 case CKM_SHA1_RSA_PKCS: 355 return (rsa_hash_pkcs_sign_final(sess, length_only, 356 ctx, signature, sig_len)); 357 default: 358 return (CKR_MECHANISM_INVALID); 359 } 360 } 361 362 CK_RV 363 sign_mgr_sign_recover(SESSION * sess, 364 CK_BBOOL length_only, 365 SIGN_VERIFY_CONTEXT * ctx, 366 CK_BYTE * in_data, 367 CK_ULONG in_data_len, 368 CK_BYTE * out_data, 369 CK_ULONG * out_data_len) 370 { 371 if (! sess || ! ctx) { 372 return (CKR_FUNCTION_FAILED); 373 } 374 if (ctx->active == FALSE) { 375 return (CKR_OPERATION_NOT_INITIALIZED); 376 } 377 if (ctx->recover == FALSE) { 378 return (CKR_OPERATION_NOT_INITIALIZED); 379 } 380 381 // if the caller just wants the signature length, there is no reason to 382 // specify the input data. I just need the input data length 383 // 384 if ((length_only == FALSE) && (! in_data || ! out_data)) { 385 return (CKR_FUNCTION_FAILED); 386 } 387 if (ctx->multi == TRUE) { 388 return (CKR_OPERATION_ACTIVE); 389 } 390 switch (ctx->mech.mechanism) { 391 case CKM_RSA_PKCS: 392 return (rsa_pkcs_sign(sess, length_only, ctx, 393 in_data, in_data_len, 394 out_data, out_data_len)); 395 default: 396 return (CKR_MECHANISM_INVALID); 397 } 398 } 399