1*7188Smcpowers /* 2*7188Smcpowers * CDDL HEADER START 3*7188Smcpowers * 4*7188Smcpowers * The contents of this file are subject to the terms of the 5*7188Smcpowers * Common Development and Distribution License (the "License"). 6*7188Smcpowers * You may not use this file except in compliance with the License. 7*7188Smcpowers * 8*7188Smcpowers * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*7188Smcpowers * or http://www.opensolaris.org/os/licensing. 10*7188Smcpowers * See the License for the specific language governing permissions 11*7188Smcpowers * and limitations under the License. 12*7188Smcpowers * 13*7188Smcpowers * When distributing Covered Code, include this CDDL HEADER in each 14*7188Smcpowers * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*7188Smcpowers * If applicable, add the following below this CDDL HEADER, with the 16*7188Smcpowers * fields enclosed by brackets "[]" replaced with your own identifying 17*7188Smcpowers * information: Portions Copyright [yyyy] [name of copyright owner] 18*7188Smcpowers * 19*7188Smcpowers * CDDL HEADER END 20*7188Smcpowers */ 21*7188Smcpowers /* 22*7188Smcpowers * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23*7188Smcpowers * Use is subject to license terms. 24*7188Smcpowers */ 25*7188Smcpowers 26*7188Smcpowers #pragma ident "%Z%%M% %I% %E% SMI" 27*7188Smcpowers 28*7188Smcpowers #ifndef _KERNEL 29*7188Smcpowers #include <stdlib.h> 30*7188Smcpowers #endif 31*7188Smcpowers 32*7188Smcpowers #include <sys/strsun.h> 33*7188Smcpowers #include <sys/types.h> 34*7188Smcpowers #include <modes/modes.h> 35*7188Smcpowers #include <sys/crypto/common.h> 36*7188Smcpowers #include <sys/crypto/impl.h> 37*7188Smcpowers 38*7188Smcpowers /* 39*7188Smcpowers * Initialize by setting iov_or_mp to point to the current iovec or mp, 40*7188Smcpowers * and by setting current_offset to an offset within the current iovec or mp. 41*7188Smcpowers */ 42*7188Smcpowers void 43*7188Smcpowers crypto_init_ptrs(crypto_data_t *out, void **iov_or_mp, offset_t *current_offset) 44*7188Smcpowers { 45*7188Smcpowers offset_t offset; 46*7188Smcpowers 47*7188Smcpowers switch (out->cd_format) { 48*7188Smcpowers case CRYPTO_DATA_RAW: 49*7188Smcpowers *current_offset = out->cd_offset; 50*7188Smcpowers break; 51*7188Smcpowers 52*7188Smcpowers case CRYPTO_DATA_UIO: { 53*7188Smcpowers uio_t *uiop = out->cd_uio; 54*7188Smcpowers uintptr_t vec_idx; 55*7188Smcpowers 56*7188Smcpowers offset = out->cd_offset; 57*7188Smcpowers for (vec_idx = 0; vec_idx < uiop->uio_iovcnt && 58*7188Smcpowers offset >= uiop->uio_iov[vec_idx].iov_len; 59*7188Smcpowers offset -= uiop->uio_iov[vec_idx++].iov_len) 60*7188Smcpowers ; 61*7188Smcpowers 62*7188Smcpowers *current_offset = offset; 63*7188Smcpowers *iov_or_mp = (void *)vec_idx; 64*7188Smcpowers break; 65*7188Smcpowers } 66*7188Smcpowers 67*7188Smcpowers case CRYPTO_DATA_MBLK: { 68*7188Smcpowers mblk_t *mp; 69*7188Smcpowers 70*7188Smcpowers offset = out->cd_offset; 71*7188Smcpowers for (mp = out->cd_mp; mp != NULL && offset >= MBLKL(mp); 72*7188Smcpowers offset -= MBLKL(mp), mp = mp->b_cont) 73*7188Smcpowers ; 74*7188Smcpowers 75*7188Smcpowers *current_offset = offset; 76*7188Smcpowers *iov_or_mp = mp; 77*7188Smcpowers break; 78*7188Smcpowers 79*7188Smcpowers } 80*7188Smcpowers } /* end switch */ 81*7188Smcpowers } 82*7188Smcpowers 83*7188Smcpowers /* 84*7188Smcpowers * Get pointers for where in the output to copy a block of encrypted or 85*7188Smcpowers * decrypted data. The iov_or_mp argument stores a pointer to the current 86*7188Smcpowers * iovec or mp, and offset stores an offset into the current iovec or mp. 87*7188Smcpowers */ 88*7188Smcpowers void 89*7188Smcpowers crypto_get_ptrs(crypto_data_t *out, void **iov_or_mp, offset_t *current_offset, 90*7188Smcpowers uint8_t **out_data_1, size_t *out_data_1_len, uint8_t **out_data_2, 91*7188Smcpowers size_t amt) 92*7188Smcpowers { 93*7188Smcpowers offset_t offset; 94*7188Smcpowers 95*7188Smcpowers switch (out->cd_format) { 96*7188Smcpowers case CRYPTO_DATA_RAW: { 97*7188Smcpowers iovec_t *iov; 98*7188Smcpowers 99*7188Smcpowers offset = *current_offset; 100*7188Smcpowers iov = &out->cd_raw; 101*7188Smcpowers if ((offset + amt) <= iov->iov_len) { 102*7188Smcpowers /* one block fits */ 103*7188Smcpowers *out_data_1 = (uint8_t *)iov->iov_base + offset; 104*7188Smcpowers *out_data_1_len = amt; 105*7188Smcpowers *out_data_2 = NULL; 106*7188Smcpowers *current_offset = offset + amt; 107*7188Smcpowers } 108*7188Smcpowers break; 109*7188Smcpowers } 110*7188Smcpowers 111*7188Smcpowers case CRYPTO_DATA_UIO: { 112*7188Smcpowers uio_t *uio = out->cd_uio; 113*7188Smcpowers iovec_t *iov; 114*7188Smcpowers offset_t offset; 115*7188Smcpowers uintptr_t vec_idx; 116*7188Smcpowers uint8_t *p; 117*7188Smcpowers 118*7188Smcpowers offset = *current_offset; 119*7188Smcpowers vec_idx = (uintptr_t)(*iov_or_mp); 120*7188Smcpowers iov = &uio->uio_iov[vec_idx]; 121*7188Smcpowers p = (uint8_t *)iov->iov_base + offset; 122*7188Smcpowers *out_data_1 = p; 123*7188Smcpowers 124*7188Smcpowers if (offset + amt <= iov->iov_len) { 125*7188Smcpowers /* can fit one block into this iov */ 126*7188Smcpowers *out_data_1_len = amt; 127*7188Smcpowers *out_data_2 = NULL; 128*7188Smcpowers *current_offset = offset + amt; 129*7188Smcpowers } else { 130*7188Smcpowers /* one block spans two iovecs */ 131*7188Smcpowers *out_data_1_len = iov->iov_len - offset; 132*7188Smcpowers if (vec_idx == uio->uio_iovcnt) 133*7188Smcpowers return; 134*7188Smcpowers vec_idx++; 135*7188Smcpowers iov = &uio->uio_iov[vec_idx]; 136*7188Smcpowers *out_data_2 = (uint8_t *)iov->iov_base; 137*7188Smcpowers *current_offset = amt - *out_data_1_len; 138*7188Smcpowers } 139*7188Smcpowers *iov_or_mp = (void *)vec_idx; 140*7188Smcpowers break; 141*7188Smcpowers } 142*7188Smcpowers 143*7188Smcpowers case CRYPTO_DATA_MBLK: { 144*7188Smcpowers mblk_t *mp; 145*7188Smcpowers uint8_t *p; 146*7188Smcpowers 147*7188Smcpowers offset = *current_offset; 148*7188Smcpowers mp = (mblk_t *)*iov_or_mp; 149*7188Smcpowers p = mp->b_rptr + offset; 150*7188Smcpowers *out_data_1 = p; 151*7188Smcpowers if ((p + amt) <= mp->b_wptr) { 152*7188Smcpowers /* can fit one block into this mblk */ 153*7188Smcpowers *out_data_1_len = amt; 154*7188Smcpowers *out_data_2 = NULL; 155*7188Smcpowers *current_offset = offset + amt; 156*7188Smcpowers } else { 157*7188Smcpowers /* one block spans two mblks */ 158*7188Smcpowers *out_data_1_len = mp->b_wptr - p; 159*7188Smcpowers if ((mp = mp->b_cont) == NULL) 160*7188Smcpowers return; 161*7188Smcpowers *out_data_2 = mp->b_rptr; 162*7188Smcpowers *current_offset = (amt - *out_data_1_len); 163*7188Smcpowers } 164*7188Smcpowers *iov_or_mp = mp; 165*7188Smcpowers break; 166*7188Smcpowers } 167*7188Smcpowers } /* end switch */ 168*7188Smcpowers } 169*7188Smcpowers 170*7188Smcpowers void 171*7188Smcpowers crypto_free_mode_ctx(void *ctx) 172*7188Smcpowers { 173*7188Smcpowers common_ctx_t *common_ctx = (common_ctx_t *)ctx; 174*7188Smcpowers 175*7188Smcpowers if (common_ctx->cc_flags & ECB_MODE) 176*7188Smcpowers #ifdef _KERNEL 177*7188Smcpowers kmem_free(common_ctx, sizeof (ecb_ctx_t)); 178*7188Smcpowers #else 179*7188Smcpowers free(common_ctx); 180*7188Smcpowers #endif 181*7188Smcpowers else if (common_ctx->cc_flags & CBC_MODE) 182*7188Smcpowers #ifdef _KERNEL 183*7188Smcpowers kmem_free(common_ctx, sizeof (cbc_ctx_t)); 184*7188Smcpowers #else 185*7188Smcpowers free(common_ctx); 186*7188Smcpowers #endif 187*7188Smcpowers else if (common_ctx->cc_flags & CTR_MODE) 188*7188Smcpowers #ifdef _KERNEL 189*7188Smcpowers kmem_free(common_ctx, sizeof (ctr_ctx_t)); 190*7188Smcpowers #else 191*7188Smcpowers free(common_ctx); 192*7188Smcpowers #endif 193*7188Smcpowers else if (common_ctx->cc_flags & CCM_MODE) { 194*7188Smcpowers #ifdef _KERNEL 195*7188Smcpowers if (((ccm_ctx_t *)ctx)->ccm_pt_buf != NULL) 196*7188Smcpowers kmem_free(((ccm_ctx_t *)ctx)->ccm_pt_buf, 197*7188Smcpowers ((ccm_ctx_t *)ctx)->ccm_data_len); 198*7188Smcpowers 199*7188Smcpowers kmem_free(ctx, sizeof (ccm_ctx_t)); 200*7188Smcpowers #else 201*7188Smcpowers if (((ccm_ctx_t *)ctx)->ccm_pt_buf != NULL) 202*7188Smcpowers free(((ccm_ctx_t *)ctx)->ccm_pt_buf); 203*7188Smcpowers free(ctx); 204*7188Smcpowers #endif 205*7188Smcpowers } 206*7188Smcpowers } 207