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
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.
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]
24 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
25 * Use is subject to license terms.
28 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
29 /* All Rights Reserved */
32 * Portions of this source code were derived from Berkeley 4.3 BSD
33 * under license from the Regents of the University of California.
37 * DES encryption library routines
43 #include <sys/types.h>
44 #include <rpc/des_crypt.h>
46 #include <sys/ioctl.h>
48 #define getdesfd() (open("/dev/des", O_RDONLY, 0))
54 extern int __des_crypt(char *, unsigned, struct desparams
*);
56 static int common_crypt(char *, char *, unsigned, unsigned, struct desparams
*);
59 * To see if chip is installed
62 static int g_desfd
= UNOPENED
;
68 #define COPY8(src, dst) { \
69 char *a = (char *)dst; \
70 char *b = (char *)src; \
71 *a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \
72 *a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \
76 * Copy multiple of 8 bytes
78 #define DESCOPY(src, dst, len) { \
79 char *a = (char *)dst; \
80 char *b = (char *)src; \
82 for (i = (int)len; i > 0; i -= 8) { \
83 *a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \
84 *a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \
92 cbc_crypt(char *key
, char *buf
, size_t len
, unsigned int mode
, char *ivec
)
98 COPY8(ivec
, dp
.des_ivec
);
99 err
= common_crypt(key
, buf
, len
, mode
, &dp
);
100 COPY8(dp
.des_ivec
, ivec
);
106 * ECB mode encryption
109 ecb_crypt(char *key
, char *buf
, size_t len
, unsigned int mode
)
114 return (common_crypt(key
, buf
, len
, mode
, &dp
));
120 * Common code to cbc_crypt() & ecb_crypt()
123 common_crypt(char *key
, char *buf
, unsigned len
, unsigned mode
,
124 struct desparams
*desp
)
129 if ((len
% 8) != 0 || len
> DES_MAXDATA
)
130 return (DESERR_BADPARAM
);
132 ((mode
& DES_DIRMASK
) == DES_ENCRYPT
) ? ENCRYPT
: DECRYPT
;
134 desdev
= mode
& DES_DEVMASK
;
135 COPY8(key
, desp
->des_key
);
137 if (desdev
== DES_HW
) {
139 if (g_desfd
== -1 || (g_desfd
= getdesfd()) < 0) {
140 goto software
; /* no hardware device */
148 if (len
<= DES_QUICKLEN
) {
149 DESCOPY(buf
, desp
->des_data
, len
);
150 res
= ioctl(g_desfd
, DESIOCQUICK
, (char *)desp
);
151 DESCOPY(desp
->des_data
, buf
, len
);
153 desp
->des_buf
= (uchar_t
*)buf
;
154 res
= ioctl(g_desfd
, DESIOCBLOCK
, (char *)desp
);
156 return (res
== 0 ? DESERR_NONE
: DESERR_HWERROR
);
163 if (!__des_crypt(buf
, len
, desp
))
164 return (DESERR_HWERROR
);
165 return (desdev
== DES_SW
? DESERR_NONE
: DESERR_NOHWDEVICE
);
169 desN_crypt(des_block keys
[], int keynum
, char *buf
, unsigned int len
,
170 unsigned int mode
, char *ivec
)
172 unsigned int m
= mode
& (DES_ENCRYPT
| DES_DECRYPT
);
173 unsigned int flags
= mode
& ~(DES_ENCRYPT
| DES_DECRYPT
);
174 des_block svec
, dvec
;
178 return (DESERR_BADPARAM
);
180 (void) memcpy(svec
.c
, ivec
, sizeof (des_block
));
181 for (i
= 0; i
< keynum
; i
++) {
182 j
= (mode
& DES_DECRYPT
) ? keynum
- 1 - i
: i
;
183 stat
= cbc_crypt(keys
[j
].c
, buf
, len
, m
| flags
, ivec
);
184 if (mode
& DES_DECRYPT
&& i
== 0)
185 (void) memcpy(dvec
.c
, ivec
, sizeof (des_block
));
187 if (DES_FAILED(stat
))
190 m
= (m
== DES_ENCRYPT
? DES_DECRYPT
: DES_ENCRYPT
);
192 if ((mode
& DES_DECRYPT
) || i
!= keynum
- 1 || i
%2)
193 (void) memcpy(ivec
, svec
.c
, sizeof (des_block
));
196 stat
= cbc_crypt(keys
[0].c
, buf
, len
, mode
, ivec
);
198 if (mode
& DES_DECRYPT
)
199 (void) memcpy(ivec
, dvec
.c
, sizeof (des_block
));
207 __cbc_triple_crypt(des_block keys
[], char *buf
, uint_t len
,
208 uint_t mode
, char *ivec
)
210 return (desN_crypt(keys
, 3, buf
, len
, mode
, ivec
));