CK_RV SC_DigestKey(ST_SESSION_HANDLE sSession, CK_OBJECT_HANDLE hKey) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET if (st_Initialized() == FALSE) { rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } sess = session_mgr_find(hSession); if (! sess) { rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (sess->digest_ctx.active == FALSE) { rc = CKR_OPERATION_NOT_INITIALIZED; goto done; } rc = digest_mgr_digest_key(sess, &sess->digest_ctx, hKey); done: if (rc != CKR_OK) (void) digest_mgr_cleanup(&sess->digest_ctx); return (rc); }
CK_RV digest_mgr_digest_update( STDLL_TokData_t *tokdata, SESSION *sess, DIGEST_CONTEXT *ctx, CK_BYTE *data, CK_ULONG data_len ) { CK_RV rc; if (!sess || !ctx){ TRACE_ERROR("Invalid function arguments.\n"); return CKR_FUNCTION_FAILED; } if (ctx->active == FALSE){ TRACE_ERROR("%s\n", ock_err(ERR_OPERATION_NOT_INITIALIZED)); return CKR_OPERATION_NOT_INITIALIZED; } ctx->multi = TRUE; switch (ctx->mech.mechanism) { case CKM_SHA_1: case CKM_SHA256: case CKM_SHA384: case CKM_SHA512: rc = sha_hash_update(tokdata, sess, ctx, data, data_len); break; #if !(NOMD2) case CKM_MD2: rc = md2_hash_update( tokdata, sess, ctx, data, data_len ); break; #endif case CKM_MD5: rc = md5_hash_update( tokdata, sess, ctx, data, data_len ); break; default: TRACE_ERROR("%s\n", ock_err(ERR_MECHANISM_INVALID)); rc = CKR_MECHANISM_INVALID; } if (rc != CKR_OK) { digest_mgr_cleanup(ctx); // "A call to C_DigestUpdate which results in an error // terminates the current digest operation." } return rc; }
CK_RV SC_Digest(ST_SESSION_HANDLE sSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pDigest, CK_ULONG_PTR pulDigestLen) { SESSION * sess = NULL; CK_BBOOL length_only = FALSE; CK_RV rc = CKR_OK; SESS_SET if (st_Initialized() == FALSE) { rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } sess = session_mgr_find(hSession); if (! sess) { rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (! pData || ! pulDigestLen) { rc = CKR_ARGUMENTS_BAD; goto done; } if (sess->digest_ctx.active == FALSE) { rc = CKR_OPERATION_NOT_INITIALIZED; goto done; } if (! pDigest) length_only = TRUE; rc = digest_mgr_digest(sess, length_only, &sess->digest_ctx, pData, ulDataLen, pDigest, pulDigestLen); done: if (rc != CKR_BUFFER_TOO_SMALL && (rc != CKR_OK || length_only != TRUE)) (void) digest_mgr_cleanup(&sess->digest_ctx); return (rc); }
CK_RV SC_DigestUpdate(ST_SESSION_HANDLE sSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen) { SESSION * sess = NULL; CK_RV rc = CKR_OK; SESS_SET if (st_Initialized() == FALSE) { rc = CKR_CRYPTOKI_NOT_INITIALIZED; goto done; } if (! pPart && ulPartLen != 0) { rc = CKR_ARGUMENTS_BAD; goto done; } sess = session_mgr_find(hSession); if (! sess) { rc = CKR_SESSION_HANDLE_INVALID; goto done; } if (sess->digest_ctx.active == FALSE) { rc = CKR_OPERATION_NOT_INITIALIZED; goto done; } if (pPart) { rc = digest_mgr_digest_update(sess, &sess->digest_ctx, pPart, ulPartLen); } done: if (rc != CKR_OK) (void) digest_mgr_cleanup(&sess->digest_ctx); return (rc); }
CK_RV digest_mgr_init( STDLL_TokData_t *tokdata, SESSION *sess, DIGEST_CONTEXT *ctx, CK_MECHANISM *mech ) { CK_RV rc = CKR_OK; CK_BYTE * ptr = NULL; if (!sess || !ctx){ TRACE_ERROR("Invalid function arguments.\n"); return CKR_FUNCTION_FAILED; } if (ctx->active != FALSE){ TRACE_ERROR("%s\n", ock_err(ERR_OPERATION_ACTIVE)); return CKR_OPERATION_ACTIVE; } // is the mechanism supported? is the parameter present if required? // switch (mech->mechanism) { case CKM_SHA_1: case CKM_SHA256: case CKM_SHA384: case CKM_SHA512: { if (mech->ulParameterLen != 0){ TRACE_ERROR("%s\n", ock_err(ERR_MECHANISM_PARAM_INVALID)); return CKR_MECHANISM_PARAM_INVALID; } ctx->context = NULL; rc = sha_init(tokdata, sess, ctx, mech); if (rc != CKR_OK) { digest_mgr_cleanup(ctx); // to de-initialize context above TRACE_ERROR("Failed to init sha context.\n"); return rc; } } break; case CKM_MD2: { if (mech->ulParameterLen != 0){ TRACE_ERROR("%s\n", ock_err(ERR_MECHANISM_PARAM_INVALID)); return CKR_MECHANISM_PARAM_INVALID; } ctx->context_len = sizeof(MD2_CONTEXT); ctx->context = (CK_BYTE *)malloc(sizeof(MD2_CONTEXT)); if (!ctx->context){ digest_mgr_cleanup(ctx); // to de-initialize context above TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY)); return CKR_HOST_MEMORY; } memset( ctx->context, 0x0, sizeof(MD2_CONTEXT) ); } break; case CKM_MD5: { if (mech->ulParameterLen != 0){ TRACE_ERROR("%s\n", ock_err(ERR_MECHANISM_PARAM_INVALID)); return CKR_MECHANISM_PARAM_INVALID; } ctx->context_len = sizeof(MD5_CONTEXT); ctx->context = (CK_BYTE *)malloc(sizeof(MD5_CONTEXT)); if (!ctx->context){ digest_mgr_cleanup(ctx); // to de-initialize context above TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY)); return CKR_HOST_MEMORY; } ckm_md5_init( tokdata, (MD5_CONTEXT *)ctx->context ); } break; default: TRACE_ERROR("%s\n", ock_err(ERR_MECHANISM_INVALID)); return CKR_MECHANISM_INVALID; } if (mech->ulParameterLen > 0) { ptr = (CK_BYTE *)malloc(mech->ulParameterLen); if (!ptr){ digest_mgr_cleanup(ctx); // to de-initialize context above TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY)); return CKR_HOST_MEMORY; } memcpy( ptr, mech->pParameter, mech->ulParameterLen ); } ctx->mech.ulParameterLen = mech->ulParameterLen; ctx->mech.mechanism = mech->mechanism; ctx->mech.pParameter = ptr; ctx->multi = FALSE; ctx->active = TRUE; return CKR_OK; }
CK_RV digest_mgr_digest( STDLL_TokData_t *tokdata, SESSION *sess, CK_BBOOL length_only, DIGEST_CONTEXT *ctx, CK_BYTE *in_data, CK_ULONG in_data_len, CK_BYTE *out_data, CK_ULONG *out_data_len ) { CK_RV rc; if (!sess || !ctx){ TRACE_ERROR("Invalid function arguments.\n"); return CKR_FUNCTION_FAILED; } if (ctx->active == FALSE){ TRACE_ERROR("%s\n", ock_err(ERR_OPERATION_NOT_INITIALIZED)); return CKR_OPERATION_NOT_INITIALIZED; } // if the caller just wants the encrypted length, there is no reason to // specify the input data. I just need the data length // if ((length_only == FALSE) && (!in_data || !out_data)){ TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED)); rc = CKR_FUNCTION_FAILED; goto out; } if (ctx->multi == TRUE){ TRACE_ERROR("%s\n", ock_err(ERR_OPERATION_ACTIVE)); rc = CKR_OPERATION_ACTIVE; goto out; } switch (ctx->mech.mechanism) { case CKM_SHA_1: case CKM_SHA256: case CKM_SHA384: case CKM_SHA512: rc = sha_hash( tokdata, sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); break; #if !(NOMD2 ) case CKM_MD2: rc = md2_hash( tokdata, sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); break; #endif case CKM_MD5: rc = md5_hash( tokdata, sess, length_only, ctx, in_data, in_data_len, out_data, out_data_len ); break; default: TRACE_ERROR("%s\n", ock_err(ERR_MECHANISM_INVALID)); rc = CKR_MECHANISM_INVALID; } out: if ( !((rc == CKR_BUFFER_TOO_SMALL) || (rc == CKR_OK && length_only == TRUE)) ) { // "A call to C_Digest always terminates the active digest operation unless it // returns CKR_BUFFER_TOO_SMALL or is a successful call (i.e., one which returns CKR_OK) // to determine the length of the buffer needed to hold the message digest." digest_mgr_cleanup(ctx); } return rc; }
CK_RV session_mgr_set_op_state( SESSION *sess, CK_OBJECT_HANDLE encr_key, CK_OBJECT_HANDLE auth_key, CK_BYTE *data) { OP_STATE_DATA *op_data = NULL; CK_BYTE *mech_param = NULL; CK_BYTE *context = NULL; CK_BYTE *ptr1 = NULL; CK_BYTE *ptr2 = NULL; CK_BYTE *ptr3 = NULL; CK_ULONG len; void *dptr = data; if (! sess || ! data) { return (CKR_FUNCTION_FAILED); } op_data = (OP_STATE_DATA *)dptr; if (sess->session_info.state != op_data->session_state) { return (CKR_SAVED_STATE_INVALID); } switch (op_data->active_operation) { case STATE_ENCR: case STATE_DECR: { void *cptr = data + sizeof (OP_STATE_DATA); ENCR_DECR_CONTEXT *ctx = (ENCR_DECR_CONTEXT *)cptr; len = sizeof (ENCR_DECR_CONTEXT) + ctx->context_len + ctx->mech.ulParameterLen; if (len != op_data->data_len) { return (CKR_SAVED_STATE_INVALID); } if (auth_key != 0) { return (CKR_KEY_NOT_NEEDED); } if (encr_key == 0) { return (CKR_KEY_NEEDED); } ptr1 = (CK_BYTE *)ctx; ptr2 = ptr1 + sizeof (ENCR_DECR_CONTEXT); ptr3 = ptr2 + ctx->context_len; if (ctx->context_len) { context = (CK_BYTE *)malloc(ctx->context_len); if (! context) { return (CKR_HOST_MEMORY); } (void) memcpy(context, ptr2, ctx->context_len); } if (ctx->mech.ulParameterLen) { mech_param = (CK_BYTE *)malloc( ctx->mech.ulParameterLen); if (! mech_param) { if (context) free(context); return (CKR_HOST_MEMORY); } (void) memcpy(mech_param, ptr3, ctx->mech.ulParameterLen); } } break; case STATE_SIGN: case STATE_VERIFY: { void *cptr = data + sizeof (OP_STATE_DATA); SIGN_VERIFY_CONTEXT *ctx = (SIGN_VERIFY_CONTEXT *)cptr; len = sizeof (SIGN_VERIFY_CONTEXT) + ctx->context_len + ctx->mech.ulParameterLen; if (len != op_data->data_len) { return (CKR_SAVED_STATE_INVALID); } if (auth_key == 0) { return (CKR_KEY_NEEDED); } if (encr_key != 0) { return (CKR_KEY_NOT_NEEDED); } ptr1 = (CK_BYTE *)ctx; ptr2 = ptr1 + sizeof (SIGN_VERIFY_CONTEXT); ptr3 = ptr2 + ctx->context_len; if (ctx->context_len) { context = (CK_BYTE *)malloc(ctx->context_len); if (! context) { return (CKR_HOST_MEMORY); } (void) memcpy(context, ptr2, ctx->context_len); } if (ctx->mech.ulParameterLen) { mech_param = (CK_BYTE *)malloc( ctx->mech.ulParameterLen); if (! mech_param) { if (context) free(context); return (CKR_HOST_MEMORY); } (void) memcpy(mech_param, ptr3, ctx->mech.ulParameterLen); } } break; case STATE_DIGEST: { void *cptr = data + sizeof (OP_STATE_DATA); DIGEST_CONTEXT *ctx = (DIGEST_CONTEXT *)cptr; len = sizeof (DIGEST_CONTEXT) + ctx->context_len + ctx->mech.ulParameterLen; if (len != op_data->data_len) { return (CKR_SAVED_STATE_INVALID); } if (auth_key != 0) { return (CKR_KEY_NOT_NEEDED); } if (encr_key != 0) { return (CKR_KEY_NOT_NEEDED); } ptr1 = (CK_BYTE *)ctx; ptr2 = ptr1 + sizeof (DIGEST_CONTEXT); ptr3 = ptr2 + ctx->context_len; if (ctx->context_len) { context = (CK_BYTE *)malloc(ctx->context_len); if (! context) { return (CKR_HOST_MEMORY); } (void) memcpy(context, ptr2, ctx->context_len); } if (ctx->mech.ulParameterLen) { mech_param = (CK_BYTE *)malloc( ctx->mech.ulParameterLen); if (! mech_param) { if (context) free(context); return (CKR_HOST_MEMORY); } (void) memcpy(mech_param, ptr3, ctx->mech.ulParameterLen); } } break; default: return (CKR_SAVED_STATE_INVALID); } if (sess->encr_ctx.active) (void) encr_mgr_cleanup(&sess->encr_ctx); if (sess->decr_ctx.active) (void) decr_mgr_cleanup(&sess->decr_ctx); if (sess->digest_ctx.active) (void) digest_mgr_cleanup(&sess->digest_ctx); if (sess->sign_ctx.active) (void) sign_mgr_cleanup(&sess->sign_ctx); if (sess->verify_ctx.active) (void) verify_mgr_cleanup(&sess->verify_ctx); switch (op_data->active_operation) { case STATE_ENCR: (void) memcpy(&sess->encr_ctx, ptr1, sizeof (ENCR_DECR_CONTEXT)); sess->encr_ctx.key = encr_key; sess->encr_ctx.context = context; sess->encr_ctx.mech.pParameter = mech_param; break; case STATE_DECR: (void) memcpy(&sess->decr_ctx, ptr1, sizeof (ENCR_DECR_CONTEXT)); sess->decr_ctx.key = encr_key; sess->decr_ctx.context = context; sess->decr_ctx.mech.pParameter = mech_param; break; case STATE_SIGN: (void) memcpy(&sess->sign_ctx, ptr1, sizeof (SIGN_VERIFY_CONTEXT)); sess->sign_ctx.key = auth_key; sess->sign_ctx.context = context; sess->sign_ctx.mech.pParameter = mech_param; break; case STATE_VERIFY: (void) memcpy(&sess->verify_ctx, ptr1, sizeof (SIGN_VERIFY_CONTEXT)); sess->verify_ctx.key = auth_key; sess->verify_ctx.context = context; sess->verify_ctx.mech.pParameter = mech_param; break; case STATE_DIGEST: (void) memcpy(&sess->digest_ctx, ptr1, sizeof (DIGEST_CONTEXT)); sess->digest_ctx.context.ref = context; sess->digest_ctx.mech.pParameter = mech_param; break; } return (CKR_OK); }