1*10500SHai-May.Chao@Sun.COM /* 2*10500SHai-May.Chao@Sun.COM * CDDL HEADER START 3*10500SHai-May.Chao@Sun.COM * 4*10500SHai-May.Chao@Sun.COM * The contents of this file are subject to the terms of the 5*10500SHai-May.Chao@Sun.COM * Common Development and Distribution License (the "License"). 6*10500SHai-May.Chao@Sun.COM * You may not use this file except in compliance with the License. 7*10500SHai-May.Chao@Sun.COM * 8*10500SHai-May.Chao@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*10500SHai-May.Chao@Sun.COM * or http://www.opensolaris.org/os/licensing. 10*10500SHai-May.Chao@Sun.COM * See the License for the specific language governing permissions 11*10500SHai-May.Chao@Sun.COM * and limitations under the License. 12*10500SHai-May.Chao@Sun.COM * 13*10500SHai-May.Chao@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each 14*10500SHai-May.Chao@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*10500SHai-May.Chao@Sun.COM * If applicable, add the following below this CDDL HEADER, with the 16*10500SHai-May.Chao@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying 17*10500SHai-May.Chao@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner] 18*10500SHai-May.Chao@Sun.COM * 19*10500SHai-May.Chao@Sun.COM * CDDL HEADER END 20*10500SHai-May.Chao@Sun.COM */ 21*10500SHai-May.Chao@Sun.COM /* 22*10500SHai-May.Chao@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23*10500SHai-May.Chao@Sun.COM * Use is subject to license terms. 24*10500SHai-May.Chao@Sun.COM */ 25*10500SHai-May.Chao@Sun.COM 26*10500SHai-May.Chao@Sun.COM #include <sys/types.h> 27*10500SHai-May.Chao@Sun.COM #include <sys/errno.h> 28*10500SHai-May.Chao@Sun.COM #include <sys/kmem.h> 29*10500SHai-May.Chao@Sun.COM #include <sys/systm.h> 30*10500SHai-May.Chao@Sun.COM #include <sys/crypto/common.h> 31*10500SHai-May.Chao@Sun.COM #include <sys/cmn_err.h> 32*10500SHai-May.Chao@Sun.COM #include <modes/modes.h> 33*10500SHai-May.Chao@Sun.COM #define _DES_FIPS_POST 34*10500SHai-May.Chao@Sun.COM #ifndef _KERNEL 35*10500SHai-May.Chao@Sun.COM #include <stdlib.h> 36*10500SHai-May.Chao@Sun.COM #include <string.h> 37*10500SHai-May.Chao@Sun.COM #include <strings.h> 38*10500SHai-May.Chao@Sun.COM #include <stdio.h> 39*10500SHai-May.Chao@Sun.COM #include <security/cryptoki.h> 40*10500SHai-May.Chao@Sun.COM #include <cryptoutil.h> 41*10500SHai-May.Chao@Sun.COM #include "softCrypt.h" 42*10500SHai-May.Chao@Sun.COM #else 43*10500SHai-May.Chao@Sun.COM #define _DES_IMPL 44*10500SHai-May.Chao@Sun.COM #include <des/des_impl.h> 45*10500SHai-May.Chao@Sun.COM #endif 46*10500SHai-May.Chao@Sun.COM 47*10500SHai-May.Chao@Sun.COM #ifndef _KERNEL 48*10500SHai-May.Chao@Sun.COM /* 49*10500SHai-May.Chao@Sun.COM * Allocate context for the DES encryption or decryption operation, and 50*10500SHai-May.Chao@Sun.COM * generate DES or DES3 key schedule to speed up the operation. 51*10500SHai-May.Chao@Sun.COM */ 52*10500SHai-May.Chao@Sun.COM soft_des_ctx_t * 53*10500SHai-May.Chao@Sun.COM des_build_context(uint8_t *key, uint8_t *iv, CK_KEY_TYPE key_type, 54*10500SHai-May.Chao@Sun.COM CK_MECHANISM_TYPE mechanism) 55*10500SHai-May.Chao@Sun.COM { 56*10500SHai-May.Chao@Sun.COM 57*10500SHai-May.Chao@Sun.COM size_t size; 58*10500SHai-May.Chao@Sun.COM soft_des_ctx_t *soft_des_ctx; 59*10500SHai-May.Chao@Sun.COM 60*10500SHai-May.Chao@Sun.COM soft_des_ctx = calloc(1, sizeof (soft_des_ctx_t)); 61*10500SHai-May.Chao@Sun.COM if (soft_des_ctx == NULL) { 62*10500SHai-May.Chao@Sun.COM return (NULL); 63*10500SHai-May.Chao@Sun.COM } 64*10500SHai-May.Chao@Sun.COM 65*10500SHai-May.Chao@Sun.COM /* Allocate key schedule for DES or DES3 based on key type. */ 66*10500SHai-May.Chao@Sun.COM if (key_type == CKK_DES) { 67*10500SHai-May.Chao@Sun.COM soft_des_ctx->key_sched = des_alloc_keysched(&size, DES, 0); 68*10500SHai-May.Chao@Sun.COM if (soft_des_ctx->key_sched == NULL) { 69*10500SHai-May.Chao@Sun.COM free(soft_des_ctx); 70*10500SHai-May.Chao@Sun.COM return (NULL); 71*10500SHai-May.Chao@Sun.COM } 72*10500SHai-May.Chao@Sun.COM des_init_keysched(key, DES, soft_des_ctx->key_sched); 73*10500SHai-May.Chao@Sun.COM } else { 74*10500SHai-May.Chao@Sun.COM soft_des_ctx->key_sched = des_alloc_keysched(&size, DES3, 0); 75*10500SHai-May.Chao@Sun.COM if (soft_des_ctx->key_sched == NULL) { 76*10500SHai-May.Chao@Sun.COM free(soft_des_ctx); 77*10500SHai-May.Chao@Sun.COM return (NULL); 78*10500SHai-May.Chao@Sun.COM } 79*10500SHai-May.Chao@Sun.COM des_init_keysched(key, DES3, soft_des_ctx->key_sched); 80*10500SHai-May.Chao@Sun.COM } 81*10500SHai-May.Chao@Sun.COM 82*10500SHai-May.Chao@Sun.COM soft_des_ctx->keysched_len = size; 83*10500SHai-May.Chao@Sun.COM soft_des_ctx->key_type = key_type; 84*10500SHai-May.Chao@Sun.COM 85*10500SHai-May.Chao@Sun.COM if ((mechanism == CKM_DES_CBC) || (mechanism == CKM_DES3_CBC)) { 86*10500SHai-May.Chao@Sun.COM /* Save Initialization Vector (IV) in the context. */ 87*10500SHai-May.Chao@Sun.COM (void) memcpy(soft_des_ctx->ivec, iv, DES_BLOCK_LEN); 88*10500SHai-May.Chao@Sun.COM 89*10500SHai-May.Chao@Sun.COM /* Allocate a context for DES cipher-block chaining. */ 90*10500SHai-May.Chao@Sun.COM soft_des_ctx->des_cbc = (void *)des_cbc_ctx_init( 91*10500SHai-May.Chao@Sun.COM soft_des_ctx->key_sched, soft_des_ctx->keysched_len, 92*10500SHai-May.Chao@Sun.COM soft_des_ctx->ivec, soft_des_ctx->key_type); 93*10500SHai-May.Chao@Sun.COM 94*10500SHai-May.Chao@Sun.COM if (soft_des_ctx->des_cbc == NULL) { 95*10500SHai-May.Chao@Sun.COM bzero(soft_des_ctx->key_sched, 96*10500SHai-May.Chao@Sun.COM soft_des_ctx->keysched_len); 97*10500SHai-May.Chao@Sun.COM free(soft_des_ctx->key_sched); 98*10500SHai-May.Chao@Sun.COM return (NULL); 99*10500SHai-May.Chao@Sun.COM } 100*10500SHai-May.Chao@Sun.COM } 101*10500SHai-May.Chao@Sun.COM 102*10500SHai-May.Chao@Sun.COM return (soft_des_ctx); 103*10500SHai-May.Chao@Sun.COM } 104*10500SHai-May.Chao@Sun.COM 105*10500SHai-May.Chao@Sun.COM /* 106*10500SHai-May.Chao@Sun.COM * Free the DES context. 107*10500SHai-May.Chao@Sun.COM */ 108*10500SHai-May.Chao@Sun.COM void 109*10500SHai-May.Chao@Sun.COM fips_des_free_context(soft_des_ctx_t *soft_des_ctx) 110*10500SHai-May.Chao@Sun.COM { 111*10500SHai-May.Chao@Sun.COM 112*10500SHai-May.Chao@Sun.COM des_ctx_t *des_ctx; 113*10500SHai-May.Chao@Sun.COM 114*10500SHai-May.Chao@Sun.COM des_ctx = (des_ctx_t *)soft_des_ctx->des_cbc; 115*10500SHai-May.Chao@Sun.COM if (des_ctx != NULL) { 116*10500SHai-May.Chao@Sun.COM bzero(des_ctx->dc_keysched, des_ctx->dc_keysched_len); 117*10500SHai-May.Chao@Sun.COM free(soft_des_ctx->des_cbc); 118*10500SHai-May.Chao@Sun.COM } 119*10500SHai-May.Chao@Sun.COM 120*10500SHai-May.Chao@Sun.COM bzero(soft_des_ctx->key_sched, soft_des_ctx->keysched_len); 121*10500SHai-May.Chao@Sun.COM free(soft_des_ctx->key_sched); 122*10500SHai-May.Chao@Sun.COM free(soft_des_ctx); 123*10500SHai-May.Chao@Sun.COM } 124*10500SHai-May.Chao@Sun.COM #else 125*10500SHai-May.Chao@Sun.COM 126*10500SHai-May.Chao@Sun.COM static void 127*10500SHai-May.Chao@Sun.COM des_copy_block64(uint8_t *in, uint64_t *out) 128*10500SHai-May.Chao@Sun.COM { 129*10500SHai-May.Chao@Sun.COM if (IS_P2ALIGNED(in, sizeof (uint64_t))) { 130*10500SHai-May.Chao@Sun.COM /* LINTED: pointer alignment */ 131*10500SHai-May.Chao@Sun.COM out[0] = *(uint64_t *)&in[0]; 132*10500SHai-May.Chao@Sun.COM } else { 133*10500SHai-May.Chao@Sun.COM uint64_t tmp64; 134*10500SHai-May.Chao@Sun.COM 135*10500SHai-May.Chao@Sun.COM #ifdef _BIG_ENDIAN 136*10500SHai-May.Chao@Sun.COM tmp64 = (((uint64_t)in[0] << 56) | 137*10500SHai-May.Chao@Sun.COM ((uint64_t)in[1] << 48) | 138*10500SHai-May.Chao@Sun.COM ((uint64_t)in[2] << 40) | 139*10500SHai-May.Chao@Sun.COM ((uint64_t)in[3] << 32) | 140*10500SHai-May.Chao@Sun.COM ((uint64_t)in[4] << 24) | 141*10500SHai-May.Chao@Sun.COM ((uint64_t)in[5] << 16) | 142*10500SHai-May.Chao@Sun.COM ((uint64_t)in[6] << 8) | 143*10500SHai-May.Chao@Sun.COM (uint64_t)in[7]); 144*10500SHai-May.Chao@Sun.COM #else 145*10500SHai-May.Chao@Sun.COM tmp64 = (((uint64_t)in[7] << 56) | 146*10500SHai-May.Chao@Sun.COM ((uint64_t)in[6] << 48) | 147*10500SHai-May.Chao@Sun.COM ((uint64_t)in[5] << 40) | 148*10500SHai-May.Chao@Sun.COM ((uint64_t)in[4] << 32) | 149*10500SHai-May.Chao@Sun.COM ((uint64_t)in[3] << 24) | 150*10500SHai-May.Chao@Sun.COM ((uint64_t)in[2] << 16) | 151*10500SHai-May.Chao@Sun.COM ((uint64_t)in[1] << 8) | 152*10500SHai-May.Chao@Sun.COM (uint64_t)in[0]); 153*10500SHai-May.Chao@Sun.COM #endif /* _BIG_ENDIAN */ 154*10500SHai-May.Chao@Sun.COM 155*10500SHai-May.Chao@Sun.COM out[0] = tmp64; 156*10500SHai-May.Chao@Sun.COM } 157*10500SHai-May.Chao@Sun.COM } 158*10500SHai-May.Chao@Sun.COM 159*10500SHai-May.Chao@Sun.COM des_ctx_t * 160*10500SHai-May.Chao@Sun.COM des_build_context(uint8_t *key, uint8_t *iv, 161*10500SHai-May.Chao@Sun.COM des_mech_type_t mech_type) 162*10500SHai-May.Chao@Sun.COM { 163*10500SHai-May.Chao@Sun.COM int rv = CRYPTO_SUCCESS; 164*10500SHai-May.Chao@Sun.COM void *keysched; 165*10500SHai-May.Chao@Sun.COM size_t size; 166*10500SHai-May.Chao@Sun.COM des_ctx_t *des_ctx = NULL; 167*10500SHai-May.Chao@Sun.COM des_strength_t strength; 168*10500SHai-May.Chao@Sun.COM 169*10500SHai-May.Chao@Sun.COM switch (mech_type) { 170*10500SHai-May.Chao@Sun.COM case DES_ECB_MECH_INFO_TYPE: 171*10500SHai-May.Chao@Sun.COM des_ctx = ecb_alloc_ctx(KM_SLEEP); 172*10500SHai-May.Chao@Sun.COM /* FALLTHRU */ 173*10500SHai-May.Chao@Sun.COM case DES_CBC_MECH_INFO_TYPE: 174*10500SHai-May.Chao@Sun.COM strength = DES; 175*10500SHai-May.Chao@Sun.COM if (des_ctx == NULL) 176*10500SHai-May.Chao@Sun.COM des_ctx = cbc_alloc_ctx(KM_SLEEP); 177*10500SHai-May.Chao@Sun.COM break; 178*10500SHai-May.Chao@Sun.COM case DES3_ECB_MECH_INFO_TYPE: 179*10500SHai-May.Chao@Sun.COM des_ctx = ecb_alloc_ctx(KM_SLEEP); 180*10500SHai-May.Chao@Sun.COM /* FALLTHRU */ 181*10500SHai-May.Chao@Sun.COM case DES3_CBC_MECH_INFO_TYPE: 182*10500SHai-May.Chao@Sun.COM strength = DES3; 183*10500SHai-May.Chao@Sun.COM if (des_ctx == NULL) 184*10500SHai-May.Chao@Sun.COM des_ctx = cbc_alloc_ctx(KM_SLEEP); 185*10500SHai-May.Chao@Sun.COM break; 186*10500SHai-May.Chao@Sun.COM default: 187*10500SHai-May.Chao@Sun.COM return (NULL); 188*10500SHai-May.Chao@Sun.COM } 189*10500SHai-May.Chao@Sun.COM 190*10500SHai-May.Chao@Sun.COM if ((keysched = des_alloc_keysched(&size, strength, 191*10500SHai-May.Chao@Sun.COM KM_SLEEP)) == NULL) 192*10500SHai-May.Chao@Sun.COM return (NULL); 193*10500SHai-May.Chao@Sun.COM 194*10500SHai-May.Chao@Sun.COM /* 195*10500SHai-May.Chao@Sun.COM * Initialize key schedule. 196*10500SHai-May.Chao@Sun.COM * Key length is stored in the key. 197*10500SHai-May.Chao@Sun.COM */ 198*10500SHai-May.Chao@Sun.COM des_init_keysched(key, strength, keysched); 199*10500SHai-May.Chao@Sun.COM 200*10500SHai-May.Chao@Sun.COM des_ctx->dc_flags |= PROVIDER_OWNS_KEY_SCHEDULE; 201*10500SHai-May.Chao@Sun.COM des_ctx->dc_keysched_len = size; 202*10500SHai-May.Chao@Sun.COM des_ctx->dc_keysched = keysched; 203*10500SHai-May.Chao@Sun.COM 204*10500SHai-May.Chao@Sun.COM if (strength == DES3) { 205*10500SHai-May.Chao@Sun.COM des_ctx->dc_flags |= DES3_STRENGTH; 206*10500SHai-May.Chao@Sun.COM } 207*10500SHai-May.Chao@Sun.COM 208*10500SHai-May.Chao@Sun.COM switch (mech_type) { 209*10500SHai-May.Chao@Sun.COM case DES_CBC_MECH_INFO_TYPE: 210*10500SHai-May.Chao@Sun.COM case DES3_CBC_MECH_INFO_TYPE: 211*10500SHai-May.Chao@Sun.COM /* Save Initialization Vector (IV) in the context. */ 212*10500SHai-May.Chao@Sun.COM rv = cbc_init_ctx((cbc_ctx_t *)des_ctx, (char *)iv, 213*10500SHai-May.Chao@Sun.COM DES_BLOCK_LEN, DES_BLOCK_LEN, des_copy_block64); 214*10500SHai-May.Chao@Sun.COM break; 215*10500SHai-May.Chao@Sun.COM case DES_ECB_MECH_INFO_TYPE: 216*10500SHai-May.Chao@Sun.COM case DES3_ECB_MECH_INFO_TYPE: 217*10500SHai-May.Chao@Sun.COM des_ctx->dc_flags |= ECB_MODE; 218*10500SHai-May.Chao@Sun.COM } 219*10500SHai-May.Chao@Sun.COM 220*10500SHai-May.Chao@Sun.COM if (rv != CRYPTO_SUCCESS) { 221*10500SHai-May.Chao@Sun.COM if (des_ctx->dc_flags & PROVIDER_OWNS_KEY_SCHEDULE) { 222*10500SHai-May.Chao@Sun.COM bzero(keysched, size); 223*10500SHai-May.Chao@Sun.COM kmem_free(keysched, size); 224*10500SHai-May.Chao@Sun.COM } 225*10500SHai-May.Chao@Sun.COM } 226*10500SHai-May.Chao@Sun.COM 227*10500SHai-May.Chao@Sun.COM return (des_ctx); 228*10500SHai-May.Chao@Sun.COM } 229*10500SHai-May.Chao@Sun.COM 230*10500SHai-May.Chao@Sun.COM void 231*10500SHai-May.Chao@Sun.COM fips_des_free_context(des_ctx_t *des_ctx) 232*10500SHai-May.Chao@Sun.COM { 233*10500SHai-May.Chao@Sun.COM 234*10500SHai-May.Chao@Sun.COM if (des_ctx != NULL) { 235*10500SHai-May.Chao@Sun.COM if (des_ctx->dc_flags & PROVIDER_OWNS_KEY_SCHEDULE) { 236*10500SHai-May.Chao@Sun.COM ASSERT(des_ctx->dc_keysched_len != 0); 237*10500SHai-May.Chao@Sun.COM bzero(des_ctx->dc_keysched, des_ctx->dc_keysched_len); 238*10500SHai-May.Chao@Sun.COM kmem_free(des_ctx->dc_keysched, 239*10500SHai-May.Chao@Sun.COM des_ctx->dc_keysched_len); 240*10500SHai-May.Chao@Sun.COM } 241*10500SHai-May.Chao@Sun.COM } 242*10500SHai-May.Chao@Sun.COM } 243*10500SHai-May.Chao@Sun.COM #endif 244*10500SHai-May.Chao@Sun.COM 245*10500SHai-May.Chao@Sun.COM /* 246*10500SHai-May.Chao@Sun.COM * fips_des_encrypt() 247*10500SHai-May.Chao@Sun.COM * 248*10500SHai-May.Chao@Sun.COM * Arguments: 249*10500SHai-May.Chao@Sun.COM * soft_des_ctx: pointer to DES context 250*10500SHai-May.Chao@Sun.COM * in_buf: pointer to the input data to be encrypted 251*10500SHai-May.Chao@Sun.COM * ulDataLen: length of the input data 252*10500SHai-May.Chao@Sun.COM * out_buf: pointer to the output data after encryption 253*10500SHai-May.Chao@Sun.COM * pulEncryptedLen: pointer to the length of the output data 254*10500SHai-May.Chao@Sun.COM * mechanism: CKM_DES_ECB, CKM_DES3_ECB, CKM_DES_CBC, CKM_DES3_CBC 255*10500SHai-May.Chao@Sun.COM * 256*10500SHai-May.Chao@Sun.COM * Description: 257*10500SHai-May.Chao@Sun.COM * This function calls the corresponding DES low-level encrypt 258*10500SHai-May.Chao@Sun.COM * routine based on the mechanism. 259*10500SHai-May.Chao@Sun.COM * 260*10500SHai-May.Chao@Sun.COM */ 261*10500SHai-May.Chao@Sun.COM #ifndef _KERNEL 262*10500SHai-May.Chao@Sun.COM CK_RV 263*10500SHai-May.Chao@Sun.COM fips_des_encrypt(soft_des_ctx_t *soft_des_ctx, CK_BYTE_PTR in_buf, 264*10500SHai-May.Chao@Sun.COM CK_ULONG ulDataLen, CK_BYTE_PTR out_buf, 265*10500SHai-May.Chao@Sun.COM CK_ULONG_PTR pulEncryptedLen, CK_MECHANISM_TYPE mechanism) 266*10500SHai-May.Chao@Sun.COM #else 267*10500SHai-May.Chao@Sun.COM int 268*10500SHai-May.Chao@Sun.COM fips_des_encrypt(des_ctx_t *des_ctx, uint8_t *in_buf, 269*10500SHai-May.Chao@Sun.COM ulong_t ulDataLen, uint8_t *out_buf, 270*10500SHai-May.Chao@Sun.COM ulong_t *pulEncryptedLen, des_mech_type_t mechanism) 271*10500SHai-May.Chao@Sun.COM #endif 272*10500SHai-May.Chao@Sun.COM { 273*10500SHai-May.Chao@Sun.COM 274*10500SHai-May.Chao@Sun.COM CK_RV rv = CKR_OK; 275*10500SHai-May.Chao@Sun.COM int rc = 0; 276*10500SHai-May.Chao@Sun.COM ulong_t out_len; 277*10500SHai-May.Chao@Sun.COM 278*10500SHai-May.Chao@Sun.COM /* 279*10500SHai-May.Chao@Sun.COM * DES only takes input length that is a multiple of blocksize 280*10500SHai-May.Chao@Sun.COM * with the mechanism CKM_DES<n>_ECB or CKM_DES<n>_CBC. 281*10500SHai-May.Chao@Sun.COM */ 282*10500SHai-May.Chao@Sun.COM if ((ulDataLen % DES_BLOCK_LEN) != 0) { 283*10500SHai-May.Chao@Sun.COM return (CKR_DATA_LEN_RANGE); 284*10500SHai-May.Chao@Sun.COM } 285*10500SHai-May.Chao@Sun.COM 286*10500SHai-May.Chao@Sun.COM /* 287*10500SHai-May.Chao@Sun.COM * For non-padding mode, the output length will 288*10500SHai-May.Chao@Sun.COM * be same as the input length. 289*10500SHai-May.Chao@Sun.COM */ 290*10500SHai-May.Chao@Sun.COM out_len = ulDataLen; 291*10500SHai-May.Chao@Sun.COM 292*10500SHai-May.Chao@Sun.COM /* 293*10500SHai-May.Chao@Sun.COM * Begin Encryption now. 294*10500SHai-May.Chao@Sun.COM */ 295*10500SHai-May.Chao@Sun.COM switch (mechanism) { 296*10500SHai-May.Chao@Sun.COM case CKM_DES_ECB: 297*10500SHai-May.Chao@Sun.COM case CKM_DES3_ECB: 298*10500SHai-May.Chao@Sun.COM { 299*10500SHai-May.Chao@Sun.COM 300*10500SHai-May.Chao@Sun.COM ulong_t i; 301*10500SHai-May.Chao@Sun.COM uint8_t *tmp_inbuf; 302*10500SHai-May.Chao@Sun.COM uint8_t *tmp_outbuf; 303*10500SHai-May.Chao@Sun.COM 304*10500SHai-May.Chao@Sun.COM for (i = 0; i < out_len; i += DES_BLOCK_LEN) { 305*10500SHai-May.Chao@Sun.COM tmp_inbuf = &in_buf[i]; 306*10500SHai-May.Chao@Sun.COM tmp_outbuf = &out_buf[i]; 307*10500SHai-May.Chao@Sun.COM /* Crunch one block of data for DES. */ 308*10500SHai-May.Chao@Sun.COM #ifndef _KERNEL 309*10500SHai-May.Chao@Sun.COM if (soft_des_ctx->key_type == CKK_DES) 310*10500SHai-May.Chao@Sun.COM (void) des_crunch_block( 311*10500SHai-May.Chao@Sun.COM soft_des_ctx->key_sched, 312*10500SHai-May.Chao@Sun.COM tmp_inbuf, tmp_outbuf, B_FALSE); 313*10500SHai-May.Chao@Sun.COM else 314*10500SHai-May.Chao@Sun.COM (void) des3_crunch_block( 315*10500SHai-May.Chao@Sun.COM soft_des_ctx->key_sched, 316*10500SHai-May.Chao@Sun.COM tmp_inbuf, tmp_outbuf, B_FALSE); 317*10500SHai-May.Chao@Sun.COM #else 318*10500SHai-May.Chao@Sun.COM if (mechanism == DES_ECB_MECH_INFO_TYPE) 319*10500SHai-May.Chao@Sun.COM (void) des_crunch_block(des_ctx->dc_keysched, 320*10500SHai-May.Chao@Sun.COM tmp_inbuf, tmp_outbuf, B_FALSE); 321*10500SHai-May.Chao@Sun.COM else 322*10500SHai-May.Chao@Sun.COM (void) des3_crunch_block(des_ctx->dc_keysched, 323*10500SHai-May.Chao@Sun.COM tmp_inbuf, tmp_outbuf, B_FALSE); 324*10500SHai-May.Chao@Sun.COM #endif 325*10500SHai-May.Chao@Sun.COM } 326*10500SHai-May.Chao@Sun.COM 327*10500SHai-May.Chao@Sun.COM *pulEncryptedLen = out_len; 328*10500SHai-May.Chao@Sun.COM break; 329*10500SHai-May.Chao@Sun.COM } 330*10500SHai-May.Chao@Sun.COM 331*10500SHai-May.Chao@Sun.COM case CKM_DES_CBC: 332*10500SHai-May.Chao@Sun.COM case CKM_DES3_CBC: 333*10500SHai-May.Chao@Sun.COM { 334*10500SHai-May.Chao@Sun.COM crypto_data_t out; 335*10500SHai-May.Chao@Sun.COM 336*10500SHai-May.Chao@Sun.COM out.cd_format = CRYPTO_DATA_RAW; 337*10500SHai-May.Chao@Sun.COM out.cd_offset = 0; 338*10500SHai-May.Chao@Sun.COM out.cd_length = out_len; 339*10500SHai-May.Chao@Sun.COM out.cd_raw.iov_base = (char *)out_buf; 340*10500SHai-May.Chao@Sun.COM out.cd_raw.iov_len = out_len; 341*10500SHai-May.Chao@Sun.COM 342*10500SHai-May.Chao@Sun.COM /* Encrypt multiple blocks of data. */ 343*10500SHai-May.Chao@Sun.COM rc = des_encrypt_contiguous_blocks( 344*10500SHai-May.Chao@Sun.COM #ifndef _KERNEL 345*10500SHai-May.Chao@Sun.COM (des_ctx_t *)soft_des_ctx->des_cbc, 346*10500SHai-May.Chao@Sun.COM #else 347*10500SHai-May.Chao@Sun.COM des_ctx, 348*10500SHai-May.Chao@Sun.COM #endif 349*10500SHai-May.Chao@Sun.COM (char *)in_buf, out_len, &out); 350*10500SHai-May.Chao@Sun.COM 351*10500SHai-May.Chao@Sun.COM if (rc != 0) 352*10500SHai-May.Chao@Sun.COM goto encrypt_failed; 353*10500SHai-May.Chao@Sun.COM 354*10500SHai-May.Chao@Sun.COM if (rc == 0) { 355*10500SHai-May.Chao@Sun.COM *pulEncryptedLen = out_len; 356*10500SHai-May.Chao@Sun.COM break; 357*10500SHai-May.Chao@Sun.COM } 358*10500SHai-May.Chao@Sun.COM encrypt_failed: 359*10500SHai-May.Chao@Sun.COM *pulEncryptedLen = 0; 360*10500SHai-May.Chao@Sun.COM 361*10500SHai-May.Chao@Sun.COM return (CKR_DEVICE_ERROR); 362*10500SHai-May.Chao@Sun.COM 363*10500SHai-May.Chao@Sun.COM } 364*10500SHai-May.Chao@Sun.COM } /* end switch */ 365*10500SHai-May.Chao@Sun.COM 366*10500SHai-May.Chao@Sun.COM return (rv); 367*10500SHai-May.Chao@Sun.COM } 368*10500SHai-May.Chao@Sun.COM 369*10500SHai-May.Chao@Sun.COM /* 370*10500SHai-May.Chao@Sun.COM * fips_des_decrypt() 371*10500SHai-May.Chao@Sun.COM * 372*10500SHai-May.Chao@Sun.COM * Arguments: 373*10500SHai-May.Chao@Sun.COM * soft_des_ctx: pointer to DES context 374*10500SHai-May.Chao@Sun.COM * in_buf: pointer to the input data to be decrypted 375*10500SHai-May.Chao@Sun.COM * ulEncryptedLen: length of the input data 376*10500SHai-May.Chao@Sun.COM * out_buf: pointer to the output data 377*10500SHai-May.Chao@Sun.COM * pulDataLen: pointer to the length of the output data 378*10500SHai-May.Chao@Sun.COM * mechanism: CKM_DES_ECB, CKM_DES3_ECB, CKM_DES_CBC, CKM_DES3_CBC 379*10500SHai-May.Chao@Sun.COM * 380*10500SHai-May.Chao@Sun.COM * Description: 381*10500SHai-May.Chao@Sun.COM * This function calls the corresponding DES low-level decrypt 382*10500SHai-May.Chao@Sun.COM * function based on the mechanism. 383*10500SHai-May.Chao@Sun.COM * 384*10500SHai-May.Chao@Sun.COM */ 385*10500SHai-May.Chao@Sun.COM #ifndef _KERNEL 386*10500SHai-May.Chao@Sun.COM CK_RV 387*10500SHai-May.Chao@Sun.COM fips_des_decrypt(soft_des_ctx_t *soft_des_ctx, CK_BYTE_PTR in_buf, 388*10500SHai-May.Chao@Sun.COM CK_ULONG ulEncryptedLen, CK_BYTE_PTR out_buf, 389*10500SHai-May.Chao@Sun.COM CK_ULONG_PTR pulDataLen, CK_MECHANISM_TYPE mechanism) 390*10500SHai-May.Chao@Sun.COM #else 391*10500SHai-May.Chao@Sun.COM int 392*10500SHai-May.Chao@Sun.COM fips_des_decrypt(des_ctx_t *des_ctx, uint8_t *in_buf, 393*10500SHai-May.Chao@Sun.COM ulong_t ulEncryptedLen, uint8_t *out_buf, 394*10500SHai-May.Chao@Sun.COM ulong_t *pulDataLen, des_mech_type_t mechanism) 395*10500SHai-May.Chao@Sun.COM #endif 396*10500SHai-May.Chao@Sun.COM { 397*10500SHai-May.Chao@Sun.COM 398*10500SHai-May.Chao@Sun.COM CK_RV rv = CKR_OK; 399*10500SHai-May.Chao@Sun.COM int rc = 0; 400*10500SHai-May.Chao@Sun.COM ulong_t out_len; 401*10500SHai-May.Chao@Sun.COM 402*10500SHai-May.Chao@Sun.COM /* 403*10500SHai-May.Chao@Sun.COM * DES only takes input length that is a multiple of 8 bytes 404*10500SHai-May.Chao@Sun.COM * with the mechanism CKM_DES<n>_ECB, CKM_DES<n>_CBC or 405*10500SHai-May.Chao@Sun.COM * CKM_DES<n>_CBC_PAD. 406*10500SHai-May.Chao@Sun.COM */ 407*10500SHai-May.Chao@Sun.COM if ((ulEncryptedLen % DES_BLOCK_LEN) != 0) { 408*10500SHai-May.Chao@Sun.COM return (CKR_DATA_LEN_RANGE); 409*10500SHai-May.Chao@Sun.COM } 410*10500SHai-May.Chao@Sun.COM 411*10500SHai-May.Chao@Sun.COM /* Set output length same as input length. */ 412*10500SHai-May.Chao@Sun.COM out_len = ulEncryptedLen; 413*10500SHai-May.Chao@Sun.COM 414*10500SHai-May.Chao@Sun.COM /* 415*10500SHai-May.Chao@Sun.COM * Begin Decryption. 416*10500SHai-May.Chao@Sun.COM */ 417*10500SHai-May.Chao@Sun.COM switch (mechanism) { 418*10500SHai-May.Chao@Sun.COM case CKM_DES_ECB: 419*10500SHai-May.Chao@Sun.COM case CKM_DES3_ECB: 420*10500SHai-May.Chao@Sun.COM { 421*10500SHai-May.Chao@Sun.COM uint8_t *tmp_inbuf; 422*10500SHai-May.Chao@Sun.COM uint8_t *tmp_outbuf; 423*10500SHai-May.Chao@Sun.COM ulong_t i; 424*10500SHai-May.Chao@Sun.COM 425*10500SHai-May.Chao@Sun.COM for (i = 0; i < out_len; i += DES_BLOCK_LEN) { 426*10500SHai-May.Chao@Sun.COM tmp_inbuf = &in_buf[i]; 427*10500SHai-May.Chao@Sun.COM tmp_outbuf = &out_buf[i]; 428*10500SHai-May.Chao@Sun.COM /* Crunch one block of data for DES. */ 429*10500SHai-May.Chao@Sun.COM #ifndef _KERNEL 430*10500SHai-May.Chao@Sun.COM if (soft_des_ctx->key_type == CKK_DES) 431*10500SHai-May.Chao@Sun.COM (void) des_crunch_block( 432*10500SHai-May.Chao@Sun.COM soft_des_ctx->key_sched, 433*10500SHai-May.Chao@Sun.COM tmp_inbuf, tmp_outbuf, B_TRUE); 434*10500SHai-May.Chao@Sun.COM else 435*10500SHai-May.Chao@Sun.COM (void) des3_crunch_block( 436*10500SHai-May.Chao@Sun.COM soft_des_ctx->key_sched, 437*10500SHai-May.Chao@Sun.COM tmp_inbuf, tmp_outbuf, B_TRUE); 438*10500SHai-May.Chao@Sun.COM #else 439*10500SHai-May.Chao@Sun.COM if (mechanism == DES_ECB_MECH_INFO_TYPE) 440*10500SHai-May.Chao@Sun.COM (void) des_crunch_block(des_ctx->dc_keysched, 441*10500SHai-May.Chao@Sun.COM tmp_inbuf, tmp_outbuf, B_TRUE); 442*10500SHai-May.Chao@Sun.COM else 443*10500SHai-May.Chao@Sun.COM (void) des3_crunch_block(des_ctx->dc_keysched, 444*10500SHai-May.Chao@Sun.COM tmp_inbuf, tmp_outbuf, B_TRUE); 445*10500SHai-May.Chao@Sun.COM #endif 446*10500SHai-May.Chao@Sun.COM } 447*10500SHai-May.Chao@Sun.COM 448*10500SHai-May.Chao@Sun.COM *pulDataLen = out_len; 449*10500SHai-May.Chao@Sun.COM break; 450*10500SHai-May.Chao@Sun.COM } 451*10500SHai-May.Chao@Sun.COM 452*10500SHai-May.Chao@Sun.COM case CKM_DES_CBC: 453*10500SHai-May.Chao@Sun.COM case CKM_DES3_CBC: 454*10500SHai-May.Chao@Sun.COM { 455*10500SHai-May.Chao@Sun.COM crypto_data_t out; 456*10500SHai-May.Chao@Sun.COM out.cd_format = CRYPTO_DATA_RAW; 457*10500SHai-May.Chao@Sun.COM out.cd_offset = 0; 458*10500SHai-May.Chao@Sun.COM out.cd_length = out_len; 459*10500SHai-May.Chao@Sun.COM out.cd_raw.iov_base = (char *)out_buf; 460*10500SHai-May.Chao@Sun.COM out.cd_raw.iov_len = out_len; 461*10500SHai-May.Chao@Sun.COM 462*10500SHai-May.Chao@Sun.COM /* Decrypt multiple blocks of data. */ 463*10500SHai-May.Chao@Sun.COM rc = des_decrypt_contiguous_blocks( 464*10500SHai-May.Chao@Sun.COM #ifndef _KERNEL 465*10500SHai-May.Chao@Sun.COM (des_ctx_t *)soft_des_ctx->des_cbc, 466*10500SHai-May.Chao@Sun.COM #else 467*10500SHai-May.Chao@Sun.COM des_ctx, 468*10500SHai-May.Chao@Sun.COM #endif 469*10500SHai-May.Chao@Sun.COM (char *)in_buf, out_len, &out); 470*10500SHai-May.Chao@Sun.COM 471*10500SHai-May.Chao@Sun.COM if (rc != 0) 472*10500SHai-May.Chao@Sun.COM goto decrypt_failed; 473*10500SHai-May.Chao@Sun.COM 474*10500SHai-May.Chao@Sun.COM *pulDataLen = out_len; 475*10500SHai-May.Chao@Sun.COM 476*10500SHai-May.Chao@Sun.COM if (rc == 0) 477*10500SHai-May.Chao@Sun.COM break; 478*10500SHai-May.Chao@Sun.COM decrypt_failed: 479*10500SHai-May.Chao@Sun.COM *pulDataLen = 0; 480*10500SHai-May.Chao@Sun.COM 481*10500SHai-May.Chao@Sun.COM return (CKR_DEVICE_ERROR); 482*10500SHai-May.Chao@Sun.COM 483*10500SHai-May.Chao@Sun.COM } 484*10500SHai-May.Chao@Sun.COM } /* end switch */ 485*10500SHai-May.Chao@Sun.COM 486*10500SHai-May.Chao@Sun.COM return (rv); 487*10500SHai-May.Chao@Sun.COM } 488*10500SHai-May.Chao@Sun.COM 489*10500SHai-May.Chao@Sun.COM /* 490*10500SHai-May.Chao@Sun.COM * DES3 Power-On SelfTest(s). 491*10500SHai-May.Chao@Sun.COM */ 492*10500SHai-May.Chao@Sun.COM int 493*10500SHai-May.Chao@Sun.COM fips_des3_post(void) 494*10500SHai-May.Chao@Sun.COM { 495*10500SHai-May.Chao@Sun.COM 496*10500SHai-May.Chao@Sun.COM /* DES3 Known Key. */ 497*10500SHai-May.Chao@Sun.COM static uint8_t des3_known_key[] = { "ANSI Triple-DES Key Data" }; 498*10500SHai-May.Chao@Sun.COM 499*10500SHai-May.Chao@Sun.COM /* DES3-CBC Known Initialization Vector (64-bits). */ 500*10500SHai-May.Chao@Sun.COM static uint8_t des3_cbc_known_iv[] = { "Security" }; 501*10500SHai-May.Chao@Sun.COM 502*10500SHai-May.Chao@Sun.COM /* DES3 Known Plaintext (64-bits). */ 503*10500SHai-May.Chao@Sun.COM static uint8_t des3_ecb_known_plaintext[] = { "Solaris!" }; 504*10500SHai-May.Chao@Sun.COM static uint8_t des3_cbc_known_plaintext[] = { "Solaris!" }; 505*10500SHai-May.Chao@Sun.COM 506*10500SHai-May.Chao@Sun.COM /* DES3 Known Ciphertext (64-bits). */ 507*10500SHai-May.Chao@Sun.COM static uint8_t des3_ecb_known_ciphertext[] = { 508*10500SHai-May.Chao@Sun.COM 0x17, 0x0d, 0x1f, 0x13, 0xd3, 0xa0, 0x3a, 0x63 509*10500SHai-May.Chao@Sun.COM }; 510*10500SHai-May.Chao@Sun.COM 511*10500SHai-May.Chao@Sun.COM static uint8_t des3_cbc_known_ciphertext[] = { 512*10500SHai-May.Chao@Sun.COM 0x7f, 0x62, 0x44, 0xb3, 0xf8, 0x77, 0xf8, 0xf8 513*10500SHai-May.Chao@Sun.COM }; 514*10500SHai-May.Chao@Sun.COM 515*10500SHai-May.Chao@Sun.COM /* DES3 variables. */ 516*10500SHai-May.Chao@Sun.COM uint8_t des3_computed_ciphertext[FIPS_DES3_ENCRYPT_LENGTH]; 517*10500SHai-May.Chao@Sun.COM uint8_t des3_computed_plaintext[FIPS_DES3_DECRYPT_LENGTH]; 518*10500SHai-May.Chao@Sun.COM 519*10500SHai-May.Chao@Sun.COM #ifdef _KERNEL 520*10500SHai-May.Chao@Sun.COM des_ctx_t *des3_context; 521*10500SHai-May.Chao@Sun.COM #else 522*10500SHai-May.Chao@Sun.COM soft_des_ctx_t *des3_context; 523*10500SHai-May.Chao@Sun.COM #endif 524*10500SHai-May.Chao@Sun.COM 525*10500SHai-May.Chao@Sun.COM ulong_t des3_bytes_encrypted; 526*10500SHai-May.Chao@Sun.COM ulong_t des3_bytes_decrypted; 527*10500SHai-May.Chao@Sun.COM int rv; 528*10500SHai-May.Chao@Sun.COM 529*10500SHai-May.Chao@Sun.COM /* 530*10500SHai-May.Chao@Sun.COM * DES3 ECB Known Answer Encryption Test 531*10500SHai-May.Chao@Sun.COM */ 532*10500SHai-May.Chao@Sun.COM #ifdef _KERNEL 533*10500SHai-May.Chao@Sun.COM des3_context = des_build_context(des3_known_key, NULL, 534*10500SHai-May.Chao@Sun.COM DES3_ECB_MECH_INFO_TYPE); 535*10500SHai-May.Chao@Sun.COM #else 536*10500SHai-May.Chao@Sun.COM des3_context = des_build_context(des3_known_key, NULL, 537*10500SHai-May.Chao@Sun.COM CKK_DES3, CKM_DES3_ECB); 538*10500SHai-May.Chao@Sun.COM #endif 539*10500SHai-May.Chao@Sun.COM 540*10500SHai-May.Chao@Sun.COM if (des3_context == NULL) 541*10500SHai-May.Chao@Sun.COM return (CKR_HOST_MEMORY); 542*10500SHai-May.Chao@Sun.COM 543*10500SHai-May.Chao@Sun.COM #ifdef _KERNEL 544*10500SHai-May.Chao@Sun.COM rv = fips_des_encrypt(des3_context, des3_ecb_known_plaintext, 545*10500SHai-May.Chao@Sun.COM FIPS_DES3_ENCRYPT_LENGTH, des3_computed_ciphertext, 546*10500SHai-May.Chao@Sun.COM &des3_bytes_encrypted, DES3_ECB_MECH_INFO_TYPE); 547*10500SHai-May.Chao@Sun.COM #else 548*10500SHai-May.Chao@Sun.COM rv = fips_des_encrypt(des3_context, des3_ecb_known_plaintext, 549*10500SHai-May.Chao@Sun.COM FIPS_DES3_ENCRYPT_LENGTH, des3_computed_ciphertext, 550*10500SHai-May.Chao@Sun.COM &des3_bytes_encrypted, CKM_DES3_ECB); 551*10500SHai-May.Chao@Sun.COM #endif 552*10500SHai-May.Chao@Sun.COM 553*10500SHai-May.Chao@Sun.COM fips_des_free_context(des3_context); 554*10500SHai-May.Chao@Sun.COM 555*10500SHai-May.Chao@Sun.COM if ((rv != CRYPTO_SUCCESS) || 556*10500SHai-May.Chao@Sun.COM (des3_bytes_encrypted != FIPS_DES3_ENCRYPT_LENGTH) || 557*10500SHai-May.Chao@Sun.COM (memcmp(des3_computed_ciphertext, des3_ecb_known_ciphertext, 558*10500SHai-May.Chao@Sun.COM FIPS_DES3_ENCRYPT_LENGTH) != 0)) 559*10500SHai-May.Chao@Sun.COM return (CKR_DEVICE_ERROR); 560*10500SHai-May.Chao@Sun.COM 561*10500SHai-May.Chao@Sun.COM /* 562*10500SHai-May.Chao@Sun.COM * DES3 ECB Known Answer Decryption Test 563*10500SHai-May.Chao@Sun.COM */ 564*10500SHai-May.Chao@Sun.COM #ifdef _KERNEL 565*10500SHai-May.Chao@Sun.COM des3_context = des_build_context(des3_known_key, NULL, 566*10500SHai-May.Chao@Sun.COM DES3_ECB_MECH_INFO_TYPE); 567*10500SHai-May.Chao@Sun.COM #else 568*10500SHai-May.Chao@Sun.COM des3_context = des_build_context(des3_known_key, NULL, 569*10500SHai-May.Chao@Sun.COM CKK_DES3, CKM_DES3_ECB); 570*10500SHai-May.Chao@Sun.COM #endif 571*10500SHai-May.Chao@Sun.COM 572*10500SHai-May.Chao@Sun.COM if (des3_context == NULL) 573*10500SHai-May.Chao@Sun.COM return (CKR_HOST_MEMORY); 574*10500SHai-May.Chao@Sun.COM 575*10500SHai-May.Chao@Sun.COM #ifdef _KERNEL 576*10500SHai-May.Chao@Sun.COM rv = fips_des_decrypt(des3_context, des3_ecb_known_ciphertext, 577*10500SHai-May.Chao@Sun.COM FIPS_DES3_DECRYPT_LENGTH, des3_computed_plaintext, 578*10500SHai-May.Chao@Sun.COM &des3_bytes_decrypted, DES3_ECB_MECH_INFO_TYPE); 579*10500SHai-May.Chao@Sun.COM #else 580*10500SHai-May.Chao@Sun.COM rv = fips_des_decrypt(des3_context, des3_ecb_known_ciphertext, 581*10500SHai-May.Chao@Sun.COM FIPS_DES3_DECRYPT_LENGTH, des3_computed_plaintext, 582*10500SHai-May.Chao@Sun.COM &des3_bytes_decrypted, CKM_DES3_ECB); 583*10500SHai-May.Chao@Sun.COM #endif 584*10500SHai-May.Chao@Sun.COM 585*10500SHai-May.Chao@Sun.COM fips_des_free_context(des3_context); 586*10500SHai-May.Chao@Sun.COM 587*10500SHai-May.Chao@Sun.COM if ((rv != CRYPTO_SUCCESS) || 588*10500SHai-May.Chao@Sun.COM (des3_bytes_decrypted != FIPS_DES3_DECRYPT_LENGTH) || 589*10500SHai-May.Chao@Sun.COM (memcmp(des3_computed_plaintext, des3_ecb_known_plaintext, 590*10500SHai-May.Chao@Sun.COM FIPS_DES3_DECRYPT_LENGTH) != 0)) 591*10500SHai-May.Chao@Sun.COM return (CKR_DEVICE_ERROR); 592*10500SHai-May.Chao@Sun.COM 593*10500SHai-May.Chao@Sun.COM /* 594*10500SHai-May.Chao@Sun.COM * DES3 CBC Known Answer Encryption Test 595*10500SHai-May.Chao@Sun.COM */ 596*10500SHai-May.Chao@Sun.COM #ifdef _KERNEL 597*10500SHai-May.Chao@Sun.COM des3_context = des_build_context(des3_known_key, des3_cbc_known_iv, 598*10500SHai-May.Chao@Sun.COM DES3_CBC_MECH_INFO_TYPE); 599*10500SHai-May.Chao@Sun.COM #else 600*10500SHai-May.Chao@Sun.COM des3_context = des_build_context(des3_known_key, des3_cbc_known_iv, 601*10500SHai-May.Chao@Sun.COM CKK_DES3, CKM_DES3_CBC); 602*10500SHai-May.Chao@Sun.COM #endif 603*10500SHai-May.Chao@Sun.COM 604*10500SHai-May.Chao@Sun.COM if (des3_context == NULL) 605*10500SHai-May.Chao@Sun.COM return (CKR_HOST_MEMORY); 606*10500SHai-May.Chao@Sun.COM 607*10500SHai-May.Chao@Sun.COM #ifdef _KERNEL 608*10500SHai-May.Chao@Sun.COM rv = fips_des_encrypt(des3_context, des3_cbc_known_plaintext, 609*10500SHai-May.Chao@Sun.COM FIPS_DES3_ENCRYPT_LENGTH, des3_computed_ciphertext, 610*10500SHai-May.Chao@Sun.COM &des3_bytes_encrypted, DES3_CBC_MECH_INFO_TYPE); 611*10500SHai-May.Chao@Sun.COM #else 612*10500SHai-May.Chao@Sun.COM rv = fips_des_encrypt(des3_context, des3_cbc_known_plaintext, 613*10500SHai-May.Chao@Sun.COM FIPS_DES3_ENCRYPT_LENGTH, des3_computed_ciphertext, 614*10500SHai-May.Chao@Sun.COM &des3_bytes_encrypted, CKM_DES3_CBC); 615*10500SHai-May.Chao@Sun.COM #endif 616*10500SHai-May.Chao@Sun.COM 617*10500SHai-May.Chao@Sun.COM fips_des_free_context(des3_context); 618*10500SHai-May.Chao@Sun.COM 619*10500SHai-May.Chao@Sun.COM if ((rv != CRYPTO_SUCCESS) || 620*10500SHai-May.Chao@Sun.COM (des3_bytes_encrypted != FIPS_DES3_ENCRYPT_LENGTH) || 621*10500SHai-May.Chao@Sun.COM (memcmp(des3_computed_ciphertext, des3_cbc_known_ciphertext, 622*10500SHai-May.Chao@Sun.COM FIPS_DES3_ENCRYPT_LENGTH) != 0)) 623*10500SHai-May.Chao@Sun.COM return (CKR_DEVICE_ERROR); 624*10500SHai-May.Chao@Sun.COM 625*10500SHai-May.Chao@Sun.COM /* 626*10500SHai-May.Chao@Sun.COM * DES3 CBC Known Answer Decryption Test 627*10500SHai-May.Chao@Sun.COM */ 628*10500SHai-May.Chao@Sun.COM #ifdef _KERNEL 629*10500SHai-May.Chao@Sun.COM des3_context = des_build_context(des3_known_key, des3_cbc_known_iv, 630*10500SHai-May.Chao@Sun.COM DES3_CBC_MECH_INFO_TYPE); 631*10500SHai-May.Chao@Sun.COM #else 632*10500SHai-May.Chao@Sun.COM des3_context = des_build_context(des3_known_key, des3_cbc_known_iv, 633*10500SHai-May.Chao@Sun.COM CKK_DES3, CKM_DES3_CBC); 634*10500SHai-May.Chao@Sun.COM #endif 635*10500SHai-May.Chao@Sun.COM 636*10500SHai-May.Chao@Sun.COM if (des3_context == NULL) 637*10500SHai-May.Chao@Sun.COM return (CKR_HOST_MEMORY); 638*10500SHai-May.Chao@Sun.COM 639*10500SHai-May.Chao@Sun.COM #ifdef _KERNEL 640*10500SHai-May.Chao@Sun.COM rv = fips_des_decrypt(des3_context, des3_cbc_known_ciphertext, 641*10500SHai-May.Chao@Sun.COM FIPS_DES3_DECRYPT_LENGTH, des3_computed_plaintext, 642*10500SHai-May.Chao@Sun.COM &des3_bytes_decrypted, DES3_CBC_MECH_INFO_TYPE); 643*10500SHai-May.Chao@Sun.COM #else 644*10500SHai-May.Chao@Sun.COM rv = fips_des_decrypt(des3_context, des3_cbc_known_ciphertext, 645*10500SHai-May.Chao@Sun.COM FIPS_DES3_DECRYPT_LENGTH, des3_computed_plaintext, 646*10500SHai-May.Chao@Sun.COM &des3_bytes_decrypted, CKM_DES3_CBC); 647*10500SHai-May.Chao@Sun.COM #endif 648*10500SHai-May.Chao@Sun.COM 649*10500SHai-May.Chao@Sun.COM fips_des_free_context(des3_context); 650*10500SHai-May.Chao@Sun.COM 651*10500SHai-May.Chao@Sun.COM if ((rv != CRYPTO_SUCCESS) || 652*10500SHai-May.Chao@Sun.COM (des3_bytes_decrypted != FIPS_DES3_DECRYPT_LENGTH) || 653*10500SHai-May.Chao@Sun.COM (memcmp(des3_computed_plaintext, des3_cbc_known_plaintext, 654*10500SHai-May.Chao@Sun.COM FIPS_DES3_DECRYPT_LENGTH) != 0)) 655*10500SHai-May.Chao@Sun.COM return (CKR_DEVICE_ERROR); 656*10500SHai-May.Chao@Sun.COM 657*10500SHai-May.Chao@Sun.COM return (CKR_OK); 658*10500SHai-May.Chao@Sun.COM } 659