1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 28 /* All Rights Reserved */ 29 30 /* 31 * Portions of this source code were derived from Berkeley 4.3 BSD 32 * under license from the Regents of the University of California. 33 */ 34 35 #pragma ident "%Z%%M% %I% %E% SMI" 36 37 /* 38 * des_crypt.c, DES encryption library routines 39 */ 40 41 #include <unistd.h> 42 #include <fcntl.h> 43 #include <sys/types.h> 44 #include <rpc/trace.h> 45 #include <rpc/des_crypt.h> 46 /* EXPORT DELETE START */ 47 #ifdef sun 48 #include <sys/ioctl.h> 49 #include <sys/des.h> 50 #ifdef _KERNEL 51 #include <sys/conf.h> 52 #define getdesfd() (cdevsw[11].d_open(0, 0) ? -1 : 0) 53 #define ioctl(a, b, c) (cdevsw[11].d_ioctl(0, b, c, 0) ? -1 : 0) 54 #ifndef CRYPT 55 #define _des_crypt(a, b, c) 0 56 #endif 57 #else 58 #define getdesfd() (open("/dev/des", 0, 0)) 59 #endif 60 #else 61 #include <des/des.h> 62 #endif 63 /* EXPORT DELETE END */ 64 #include <rpc/rpc.h> 65 /* EXPORT DELETE START */ 66 67 extern int __des_crypt(); 68 69 static int common_crypt(); 70 71 /* 72 * To see if chip is installed 73 */ 74 #define UNOPENED (-2) 75 static int g_desfd = UNOPENED; 76 77 78 /* 79 * Copy 8 bytes 80 */ 81 #define COPY8(src, dst) { \ 82 register char *a = (char *) dst; \ 83 register char *b = (char *) src; \ 84 *a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \ 85 *a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \ 86 } 87 88 /* 89 * Copy multiple of 8 bytes 90 */ 91 #define DESCOPY(src, dst, len) { \ 92 register char *a = (char *) dst; \ 93 register char *b = (char *) src; \ 94 register int i; \ 95 for (i = (int) len; i > 0; i -= 8) { \ 96 *a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \ 97 *a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \ 98 } \ 99 } 100 /* EXPORT DELETE END */ 101 102 /* 103 * CBC mode encryption 104 */ 105 int 106 cbc_crypt(char *key, char *buf, size_t len, unsigned int mode, char *ivec) 107 { 108 /* EXPORT DELETE START */ 109 int err; 110 struct desparams dp; 111 112 trace3(TR_cbc_crypt, 0, len, mode); 113 dp.des_mode = CBC; 114 COPY8(ivec, dp.des_ivec); 115 err = common_crypt(key, buf, len, mode, &dp); 116 COPY8(dp.des_ivec, ivec); 117 trace3(TR_cbc_crypt, 1, len, mode); 118 return (err); 119 #if 0 120 /* EXPORT DELETE END */ 121 return (DESERR_HWERROR); 122 /* EXPORT DELETE START */ 123 #endif 124 /* EXPORT DELETE END */ 125 } 126 127 128 /* 129 * ECB mode encryption 130 */ 131 int 132 ecb_crypt(char *key, char *buf, size_t len, unsigned int mode) 133 { 134 /* EXPORT DELETE START */ 135 struct desparams dp; 136 int dummy; 137 138 trace3(TR_ecb_crypt, 0, len, mode); 139 dp.des_mode = ECB; 140 dummy = common_crypt(key, buf, len, mode, &dp); 141 trace3(TR_ecb_crypt, 1, len, mode); 142 return (dummy); 143 #if 0 144 /* EXPORT DELETE END */ 145 return (DESERR_HWERROR); 146 /* EXPORT DELETE START */ 147 #endif 148 /* EXPORT DELETE END */ 149 } 150 151 152 /* EXPORT DELETE START */ 153 154 /* 155 * Common code to cbc_crypt() & ecb_crypt() 156 */ 157 static int 158 common_crypt(key, buf, len, mode, desp) 159 char *key; 160 char *buf; 161 register unsigned len; 162 unsigned mode; 163 register struct desparams *desp; 164 { 165 register int desdev; 166 register int res; 167 168 trace3(TR_common_crypt, 0, len, mode); 169 if ((len % 8) != 0 || len > DES_MAXDATA) { 170 trace3(TR_common_crypt, 1, len, mode); 171 return (DESERR_BADPARAM); 172 } 173 desp->des_dir = 174 ((mode & DES_DIRMASK) == DES_ENCRYPT) ? ENCRYPT : DECRYPT; 175 176 desdev = mode & DES_DEVMASK; 177 COPY8(key, desp->des_key); 178 #ifdef sun 179 if (desdev == DES_HW) { 180 if (g_desfd < 0) { 181 if (g_desfd == -1 || (g_desfd = getdesfd()) < 0) { 182 goto software; /* no hardware device */ 183 } 184 } 185 186 /* 187 * hardware 188 */ 189 desp->des_len = len; 190 if (len <= DES_QUICKLEN) { 191 DESCOPY(buf, desp->des_data, len); 192 res = ioctl(g_desfd, DESIOCQUICK, (char *) desp); 193 DESCOPY(desp->des_data, buf, len); 194 } else { 195 desp->des_buf = (u_char *) buf; 196 res = ioctl(g_desfd, DESIOCBLOCK, (char *) desp); 197 } 198 trace3(TR_common_crypt, 1, len, mode); 199 return (res == 0 ? DESERR_NONE : DESERR_HWERROR); 200 } 201 software: 202 #endif 203 /* 204 * software 205 */ 206 if (!__des_crypt(buf, len, desp)) { 207 trace3(TR_common_crypt, 1, len, mode); 208 return (DESERR_HWERROR); 209 } 210 trace3(TR_common_crypt, 1, len, mode); 211 return (desdev == DES_SW ? DESERR_NONE : DESERR_NOHWDEVICE); 212 } 213 /* EXPORT DELETE END */ 214 215 /* EXPORT DELETE START */ 216 static int 217 desN_crypt(des_block keys[], int keynum, char *buf, unsigned int len, 218 unsigned int mode, char *ivec) 219 { 220 unsigned int m = mode & (DES_ENCRYPT | DES_DECRYPT); 221 unsigned int flags = mode & ~(DES_ENCRYPT | DES_DECRYPT); 222 des_block svec, dvec; 223 int i, j, stat; 224 225 if (keynum < 1) 226 return (DESERR_BADPARAM); 227 228 (void) memcpy(svec.c, ivec, sizeof (des_block)); 229 for (i = 0; i < keynum; i++) { 230 j = (mode & DES_DECRYPT) ? keynum - 1 - i : i; 231 stat = cbc_crypt(keys[j].c, buf, len, m | flags, ivec); 232 if (mode & DES_DECRYPT && i == 0) 233 (void) memcpy(dvec.c, ivec, sizeof (des_block)); 234 235 if (DES_FAILED(stat)) 236 return (stat); 237 238 m = (m == DES_ENCRYPT ? DES_DECRYPT : DES_ENCRYPT); 239 240 if ((mode & DES_DECRYPT) || i != keynum - 1 || i%2) 241 (void) memcpy(ivec, svec.c, sizeof (des_block)); 242 } 243 if (keynum % 2 == 0) 244 stat = cbc_crypt(keys[0].c, buf, len, mode, ivec); 245 246 if (mode & DES_DECRYPT) 247 (void) memcpy(ivec, dvec.c, sizeof (des_block)); 248 249 return (stat); 250 } 251 /* EXPORT DELETE END */ 252 253 254 255 int 256 __cbc_triple_crypt(des_block keys[], char *buf, u_int len, 257 u_int mode, char *ivec) 258 { 259 /* EXPORT DELETE START */ 260 trace3(T___cbc_triple_crypt, 0, len, mode); 261 return (desN_crypt(keys, 3, buf, len, mode, ivec)); 262 #if 0 263 /* EXPORT DELETE END */ 264 return (DESERR_HWERROR); 265 /* EXPORT DELETE START */ 266 #endif 267 /* EXPORT DELETE END */ 268 } 269