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 /* 24 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 25 * Use is subject to license terms. 26 */ 27 28 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ 29 /* All Rights Reserved */ 30 31 /* 32 * Portions of this source code were derived from Berkeley 4.3 BSD 33 * under license from the Regents of the University of California. 34 */ 35 36 #pragma ident "%Z%%M% %I% %E% SMI" 37 /*LINTLIBRARY*/ 38 39 /* 40 * DES encryption library routines 41 */ 42 43 #include "des_synonyms.h" 44 #include <sys/types.h> 45 #include <rpc/des_crypt.h> 46 #include <sys/stat.h> 47 #include <fcntl.h> 48 #include <unistd.h> 49 #include <stropts.h> 50 #ifdef sun 51 #include <sys/ioctl.h> 52 #include <sys/des.h> 53 #ifdef _KERNEL 54 #include <sys/conf.h> 55 #define getdesfd() (cdevsw[11].d_open(0, 0) ? -1 : 0) 56 #define ioctl(a, b, c) (cdevsw[11].d_ioctl(0, b, c, 0) ? -1 : 0) 57 #ifndef CRYPT 58 #define __des_crypt(a, b, c) 0 59 #endif 60 #else 61 #define getdesfd() (open("/dev/des", 0, 0)) 62 #endif 63 #else 64 #include <des/des.h> 65 #endif 66 67 #include "des_soft.h" 68 69 /* 70 * To see if chip is installed 71 */ 72 #define UNOPENED (-2) 73 74 /* 75 * Copy 8 bytes 76 */ 77 #define COPY8(src, dst) { \ 78 char *a = (char *) dst; \ 79 char *b = (char *) src; \ 80 *a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \ 81 *a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \ 82 } 83 84 /* 85 * Copy multiple of 8 bytes 86 */ 87 #define DESCOPY(src, dst, len) { \ 88 char *a = (char *) dst; \ 89 char *b = (char *) src; \ 90 int i; \ 91 for (i = (int) len; i > 0; i -= 8) { \ 92 *a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \ 93 *a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \ 94 } \ 95 } 96 static int common_crypt(char *, char *, unsigned, unsigned, struct desparams *); 97 98 /* 99 * CBC mode encryption 100 */ 101 int 102 cbc_crypt(char *key, char *buf, size_t len, unsigned int mode, char *ivec) 103 { 104 int err = 0; 105 106 /* EXPORT DELETE START */ 107 struct desparams dp; 108 109 dp.des_mode = CBC; 110 COPY8(ivec, dp.des_ivec); 111 err = common_crypt(key, buf, len, mode, &dp); 112 COPY8(dp.des_ivec, ivec); 113 /* EXPORT DELETE END */ 114 return (err); 115 } 116 117 118 /* 119 * ECB mode encryption 120 */ 121 int 122 ecb_crypt(char *key, char *buf, size_t len, unsigned int mode) 123 { 124 int ret = 0; 125 126 /* EXPORT DELETE START */ 127 struct desparams dp; 128 129 dp.des_mode = ECB; 130 ret = common_crypt(key, buf, len, mode, &dp); 131 /* EXPORT DELETE END */ 132 return (ret); 133 } 134 135 136 /* EXPORT DELETE START */ 137 /* 138 * Common code to cbc_crypt() & ecb_crypt() 139 */ 140 static int 141 common_crypt(char *key, char *buf, unsigned len, unsigned mode, struct desparams *desp) 142 { 143 int desdev; 144 int res; 145 int g_desfd = UNOPENED; 146 147 if ((len % 8) != 0 || len > DES_MAXDATA) { 148 return (DESERR_BADPARAM); 149 } 150 desp->des_dir = 151 ((mode & DES_DIRMASK) == DES_ENCRYPT) ? ENCRYPT : DECRYPT; 152 153 desdev = mode & DES_DEVMASK; 154 COPY8(key, desp->des_key); 155 #ifdef sun 156 if (desdev == DES_HW) { 157 if (g_desfd < 0) { 158 if (g_desfd == -1 || (g_desfd = getdesfd()) < 0) { 159 goto software; /* no hardware device */ 160 } 161 } 162 163 /* 164 * hardware 165 */ 166 desp->des_len = len; 167 if (len <= DES_QUICKLEN) { 168 DESCOPY(buf, desp->des_data, len); 169 res = ioctl(g_desfd, (int)DESIOCQUICK, (char *) desp); 170 DESCOPY(desp->des_data, buf, len); 171 } else { 172 desp->des_buf = (u_char *) buf; 173 res = ioctl(g_desfd, (int)DESIOCBLOCK, (char *) desp); 174 } 175 return (res == 0 ? DESERR_NONE : DESERR_HWERROR); 176 } 177 software: 178 #endif 179 /* 180 * software 181 */ 182 if (!__des_crypt(buf, len, desp)) { 183 return (DESERR_HWERROR); 184 } 185 return (desdev == DES_SW ? DESERR_NONE : DESERR_NOHWDEVICE); 186 } 187 /* EXPORT DELETE END */ 188