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 (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 
  27 /*      Copyright (c) 1983, 1984, 1985, 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 encryption library routines
  39  */
  40 
  41 #include <sys/types.h>
  42 #include <rpc/des_crypt.h>
  43 #include <sys/stat.h>
  44 #include <fcntl.h>
  45 #include <unistd.h>
  46 #include <stropts.h>
  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 
  64 #include "des_soft.h"
  65 
  66 /*
  67  * To see if chip is installed
  68  */
  69 #define UNOPENED (-2)
  70 
  71 /*
  72  * Copy 8 bytes
  73  */
  74 #define COPY8(src, dst) { \
  75         char *a = (char *)dst; \
  76         char *b = (char *)src; \
  77         *a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \
  78         *a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \
  79 }
  80 
  81 /*
  82  * Copy multiple of 8 bytes
  83  */
  84 #define DESCOPY(src, dst, len) { \
  85         char *a = (char *)dst; \
  86         char *b = (char *)src; \
  87         int i; \
  88         for (i = (int)len; i > 0; i -= 8) { \
  89                 *a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \
  90                 *a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \
  91         } \
  92 }
  93 static int common_crypt(char *, char *, unsigned, unsigned, struct desparams *);
  94 
  95 /*
  96  * CBC mode encryption
  97  */
  98 int
  99 cbc_crypt(char *key, char *buf, size_t len, unsigned int mode, char *ivec)
 100 {
 101         int err = 0;
 102 
 103 /* EXPORT DELETE START */
 104         struct desparams dp;
 105 
 106         dp.des_mode = CBC;
 107         COPY8(ivec, dp.des_ivec);
 108         err = common_crypt(key, buf, len, mode, &dp);
 109         COPY8(dp.des_ivec, ivec);
 110 /* EXPORT DELETE END */
 111         return (err);
 112 }
 113 
 114 
 115 /*
 116  * ECB mode encryption
 117  */
 118 int
 119 ecb_crypt(char *key, char *buf, size_t len, unsigned int mode)
 120 {
 121         int ret = 0;
 122 
 123 /* EXPORT DELETE START */
 124         struct desparams dp;
 125 
 126         dp.des_mode = ECB;
 127         ret = common_crypt(key, buf, len, mode, &dp);
 128 /* EXPORT DELETE END */
 129         return (ret);
 130 }
 131 
 132 
 133 /* EXPORT DELETE START */
 134 /*
 135  * Common code to cbc_crypt() & ecb_crypt()
 136  */
 137 static int
 138 common_crypt(char *key, char *buf, unsigned len,
 139     unsigned mode, struct desparams *desp)
 140 {
 141         int desdev;
 142         int res;
 143         int g_desfd = UNOPENED;
 144 
 145         if ((len % 8) != 0 || len > DES_MAXDATA) {
 146                 return (DESERR_BADPARAM);
 147         }
 148         desp->des_dir =
 149             ((mode & DES_DIRMASK) == DES_ENCRYPT) ? ENCRYPT : DECRYPT;
 150 
 151         desdev = mode & DES_DEVMASK;
 152         COPY8(key, desp->des_key);
 153 #ifdef sun
 154         if (desdev == DES_HW) {
 155                 if (g_desfd < 0) {
 156                         if (g_desfd == -1 || (g_desfd = getdesfd()) < 0) {
 157                                 goto software;  /* no hardware device */
 158                         }
 159                 }
 160 
 161                 /*
 162                  * hardware
 163                  */
 164                 desp->des_len = len;
 165                 if (len <= DES_QUICKLEN) {
 166                         DESCOPY(buf, desp->des_data, len);
 167                         res = ioctl(g_desfd, (int)DESIOCQUICK, (char *)desp);
 168                         DESCOPY(desp->des_data, buf, len);
 169                 } else {
 170                         desp->des_buf = (uchar_t *)buf;
 171                         res = ioctl(g_desfd, (int)DESIOCBLOCK, (char *)desp);
 172                 }
 173                 return (res == 0 ? DESERR_NONE : DESERR_HWERROR);
 174         }
 175 software:
 176 #endif
 177         /*
 178          * software
 179          */
 180         if (!__des_crypt(buf, len, desp)) {
 181                 return (DESERR_HWERROR);
 182         }
 183         return (desdev == DES_SW ? DESERR_NONE : DESERR_NOHWDEVICE);
 184 }
 185 /* EXPORT DELETE END */