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) 1984, 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 
  38 /*
  39  * DES encryption library routines
  40  */
  41 
  42 #include "mt.h"
  43 #include <unistd.h>
  44 #include <fcntl.h>
  45 #include <sys/types.h>
  46 #include <rpc/des_crypt.h>
  47 /* EXPORT DELETE START */
  48 #ifdef sun
  49 #include <sys/ioctl.h>
  50 #include <sys/des.h>
  51 #define getdesfd()      (open("/dev/des", 0, 0))
  52 #else
  53 #include <des/des.h>
  54 #endif
  55 /* EXPORT DELETE END */
  56 #include <rpc/rpc.h>
  57 /* EXPORT DELETE START */
  58 
  59 extern int __des_crypt(char *, unsigned, struct desparams *);
  60 
  61 static int common_crypt(char *, char *, unsigned, unsigned, struct desparams *);
  62 
  63 /*
  64  * To see if chip is installed
  65  */
  66 #define UNOPENED (-2)
  67 static int g_desfd = UNOPENED;
  68 
  69 
  70 /*
  71  * Copy 8 bytes
  72  */
  73 #define COPY8(src, dst) { \
  74         char *a = (char *)dst; \
  75         char *b = (char *)src; \
  76         *a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \
  77         *a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \
  78 }
  79 
  80 /*
  81  * Copy multiple of 8 bytes
  82  */
  83 #define DESCOPY(src, dst, len) { \
  84         char *a = (char *)dst; \
  85         char *b = (char *)src; \
  86         int i; \
  87         for (i = (int)len; i > 0; i -= 8) { \
  88                 *a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \
  89                 *a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \
  90         } \
  91 }
  92 /* EXPORT DELETE END */
  93 
  94 /*
  95  * CBC mode encryption
  96  */
  97 int
  98 cbc_crypt(char *key, char *buf, size_t len, unsigned int mode, char *ivec)
  99 {
 100 /* EXPORT DELETE START */
 101         int err;
 102         struct desparams dp;
 103 
 104         dp.des_mode = CBC;
 105         COPY8(ivec, dp.des_ivec);
 106         err = common_crypt(key, buf, len, mode, &dp);
 107         COPY8(dp.des_ivec, ivec);
 108         return (err);
 109 #if 0
 110 /* EXPORT DELETE END */
 111         return (DESERR_HWERROR);
 112 /* EXPORT DELETE START */
 113 #endif
 114 /* EXPORT DELETE END */
 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 /* EXPORT DELETE START */
 125         struct desparams dp;
 126 
 127         dp.des_mode = ECB;
 128         return (common_crypt(key, buf, len, mode, &dp));
 129 #if 0
 130 /* EXPORT DELETE END */
 131         return (DESERR_HWERROR);
 132 /* EXPORT DELETE START */
 133 #endif
 134 /* EXPORT DELETE END */
 135 }
 136 
 137 
 138 /* EXPORT DELETE START */
 139 
 140 /*
 141  * Common code to cbc_crypt() & ecb_crypt()
 142  */
 143 static int
 144 common_crypt(char *key, char *buf, unsigned len, unsigned mode,
 145                                                         struct desparams *desp)
 146 {
 147         int desdev;
 148         int res;
 149 
 150         if ((len % 8) != 0 || len > DES_MAXDATA)
 151                 return (DESERR_BADPARAM);
 152         desp->des_dir =
 153                 ((mode & DES_DIRMASK) == DES_ENCRYPT) ? ENCRYPT : DECRYPT;
 154 
 155         desdev = mode & DES_DEVMASK;
 156         COPY8(key, desp->des_key);
 157 #ifdef sun
 158         if (desdev == DES_HW) {
 159                 if (g_desfd < 0) {
 160                         if (g_desfd == -1 || (g_desfd = getdesfd()) < 0) {
 161                                 goto software;  /* no hardware device */
 162                         }
 163                 }
 164 
 165                 /*
 166                  * hardware
 167                  */
 168                 desp->des_len = len;
 169                 if (len <= DES_QUICKLEN) {
 170                         DESCOPY(buf, desp->des_data, len);
 171                         res = ioctl(g_desfd, DESIOCQUICK, (char *)desp);
 172                         DESCOPY(desp->des_data, buf, len);
 173                 } else {
 174                         desp->des_buf = (uchar_t *)buf;
 175                         res = ioctl(g_desfd, DESIOCBLOCK, (char *)desp);
 176                 }
 177                 return (res == 0 ? DESERR_NONE : DESERR_HWERROR);
 178         }
 179 software:
 180 #endif
 181         /*
 182          * software
 183          */
 184         if (!__des_crypt(buf, len, desp))
 185                 return (DESERR_HWERROR);
 186         return (desdev == DES_SW ? DESERR_NONE : DESERR_NOHWDEVICE);
 187 }
 188 /* EXPORT DELETE END */
 189 
 190 /* EXPORT DELETE START */
 191 static int
 192 desN_crypt(des_block keys[], int keynum, char *buf, unsigned int len,
 193                 unsigned int mode, char *ivec)
 194 {
 195         unsigned int m = mode & (DES_ENCRYPT | DES_DECRYPT);
 196         unsigned int flags = mode & ~(DES_ENCRYPT | DES_DECRYPT);
 197         des_block svec, dvec;
 198         int i, j, stat;
 199 
 200         if (keynum < 1)
 201                 return (DESERR_BADPARAM);
 202 
 203         (void) memcpy(svec.c, ivec, sizeof (des_block));
 204         for (i = 0; i < keynum; i++) {
 205                 j = (mode & DES_DECRYPT) ? keynum - 1 - i : i;
 206                 stat = cbc_crypt(keys[j].c, buf, len, m | flags, ivec);
 207                 if (mode & DES_DECRYPT && i == 0)
 208                         (void) memcpy(dvec.c, ivec, sizeof (des_block));
 209 
 210                 if (DES_FAILED(stat))
 211                         return (stat);
 212 
 213                 m = (m == DES_ENCRYPT ? DES_DECRYPT : DES_ENCRYPT);
 214 
 215                 if ((mode & DES_DECRYPT) || i != keynum - 1 || i%2)
 216                         (void) memcpy(ivec, svec.c, sizeof (des_block));
 217         }
 218         if (keynum % 2 == 0)
 219                 stat = cbc_crypt(keys[0].c, buf, len, mode, ivec);
 220 
 221         if (mode & DES_DECRYPT)
 222                 (void) memcpy(ivec, dvec.c, sizeof (des_block));
 223 
 224         return (stat);
 225 }
 226 /* EXPORT DELETE END */
 227 
 228 
 229 
 230 int
 231 __cbc_triple_crypt(des_block keys[], char *buf,  uint_t len,
 232                         uint_t mode, char *ivec)
 233 {
 234 /* EXPORT DELETE START */
 235         return (desN_crypt(keys, 3, buf, len, mode, ivec));
 236 #if 0
 237 /* EXPORT DELETE END */
 238         return (DESERR_HWERROR);
 239 /* EXPORT DELETE START */
 240 #endif
 241 /* EXPORT DELETE END */
 242 }