]> arthur.barton.de Git - netatalk.git/blob - etc/uams/crypt.c
apply parts of the netbsd build patch by Patrick Welche <prlw1@newn.cam.ac.uk>, mostl...
[netatalk.git] / etc / uams / crypt.c
1 /*
2  * $Id: crypt.c,v 1.3 2003-06-11 07:49:52 srittau Exp $
3  *
4  * Copyright (c) 1990,1993 Regents of The University of Michigan.
5  * Copyright (c) 1999 Adrian Sun (asun@u.washington.edu)
6  * Copyright (C) 2003 Sebastian Rittau (srittau@debian.org)
7  * All Rights Reserved.  See COPYRIGHT.
8  */
9
10 #ifdef HAVE_CONFIG_H
11 #include <config.h>
12 #endif
13
14 #include <assert.h>
15 #include <ctype.h>
16 #include <stdlib.h>
17 #include <string.h>
18 #include <sys/types.h>
19
20 #ifdef HAVE_GCRYPT
21 #include <gcrypt.h>
22 #define DES_KEY_SZ 8
23 #else /* HAVE_GCRYPT */
24 #include <des.h>
25 #endif /* HAVE_GCRYPT */
26
27 #include <atalk/afp.h>
28
29 #include "crypt.h"
30
31 /* Cannot perform in-place operation. dstlen must be at least srclen*2. */
32 void atalk_hexify(u_int8_t *dst, size_t dstlen, const u_int8_t *src, size_t srclen)
33 {
34         static const unsigned char hextable[] = "0123456789ABCDEF";
35
36         assert(dstlen >= srclen * 2);
37
38         for (; srclen > 0; dst += 2, src++, dstlen -= 2, srclen--) {
39                 dst[0] = hextable[(*src & 0xF0) >> 4];
40                 dst[1] = hextable[(*src & 0x0F)];
41         }
42
43         memset(dst, 0, dstlen);
44 }
45
46 /* Can perform in-place operation. dstlen must be at least srclen/2. */
47 #define unhex(x)  (isdigit(x) ? (x) - '0' : toupper(x) + 10 - 'A')
48 void atalk_unhexify(u_int8_t *dst, size_t dstlen, const u_int8_t *src, size_t srclen)
49 {
50         assert(srclen % 2 == 0);
51         assert(dstlen >= srclen / 2);
52
53         for (; srclen > 0; dst++, src += 2, dstlen--, srclen -= 2)
54                 *dst = (unhex(src[0]) << 4) | unhex(src[1]);
55
56         memset(dst, 0, dstlen);
57 }
58
59 int atalk_encrypt_start(CryptHandle *handle, u_int8_t *key)
60 {
61 #ifdef HAVE_GCRYPT
62         GcryCipherHd hd;
63
64         hd = gcry_cipher_open(GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0);
65         if (!hd)
66                 return AFPERR_PARAM;
67         gcry_cipher_setkey(hd, key, DES_KEY_SZ);
68
69         *handle = hd;
70
71         return AFP_OK;
72 #else /* HAVE_GCRYPT */
73         DES_key_schedule *sched = malloc(sizeof(DES_key_schedule));
74         DES_set_key_unchecked((DES_cblock *) key, sched);
75
76         *handle = sched;
77
78         return AFP_OK;
79 #endif /* HAVE_GCRYPT */
80 }
81
82 int atalk_encrypt_do(CryptHandle handle, u_int8_t *dst, u_int8_t *src)
83 {
84 #ifdef HAVE_GCRYPT
85         int ret;
86
87         ret = gcry_cipher_encrypt(*(GcryCipherHd *) handle,
88                                   dst, DES_KEY_SZ, src, DES_KEY_SZ);
89
90         return ret == 0 ? AFP_OK : AFPERR_PARAM;
91 #else /* HAVE_GCRYPT */
92         DES_ecb_encrypt((DES_cblock *) src, (DES_cblock *) dst,
93                         (DES_key_schedule *) handle, DES_ENCRYPT);
94
95         return AFP_OK;
96 #endif /* HAVE_GCRYPT */
97 }
98
99 void atalk_encrypt_end(CryptHandle handle)
100 {
101 #ifdef HAVE_GCRYPT
102         gcry_cipher_close(*(GcryCipherHd *) handle);
103 #else /* HAVE_GCRYPT */
104         memset(handle, 0, sizeof(DES_key_schedule));
105         free(handle);
106 #endif /* HAVE_GCRYPT */
107 }
108
109 int atalk_encrypt(u_int8_t *key, u_int8_t *dst, u_int8_t *src)
110 {
111 #ifdef HAVE_GCRYPT
112         GcryCipherHd hd;
113         int ret;
114                                                                                 
115         hd = gcry_cipher_open(GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0);
116         if (!hd)
117                 return AFPERR_PARAM;
118         gcry_cipher_setkey(hd, key, DES_KEY_SZ);
119
120         ret = gcry_cipher_encrypt(hd, dst, DES_KEY_SZ, src, DES_KEY_SZ);
121
122         gcry_cipher_close(hd);
123
124         return ret == 0 ? AFP_OK : AFPERR_PARAM;
125 #else /* HAVE_GCRYPT */
126         DES_key_schedule sched;
127
128         DES_set_key_unchecked((DES_cblock *) key, &sched);
129         DES_ecb_encrypt((DES_cblock *) src, (DES_cblock *) dst,
130                         &sched, DES_ENCRYPT);
131
132         memset(&sched, 0, sizeof(sched));
133
134         return AFP_OK;
135 #endif /* HAVE_GCRYPT */
136 }
137
138 int atalk_decrypt(u_int8_t *key, u_int8_t *dst, u_int8_t *src)
139 {
140 #ifdef HAVE_GCRYPT
141         GcryCipherHd hd;
142         int ret;
143
144         hd = gcry_cipher_open(GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0);
145         if (!hd)
146                 return AFPERR_PARAM;
147         gcry_cipher_setkey(hd, key, DES_KEY_SZ);
148
149         ret = gcry_cipher_encrypt(hd, dst, DES_KEY_SZ, src, DES_KEY_SZ);
150
151         gcry_cipher_close(hd);
152
153         return ret == 0 ? AFP_OK : AFPERR_PARAM;
154 #else /* HAVE_GCRYPT */
155         DES_key_schedule sched;
156
157         DES_set_key_unchecked((DES_cblock *) key, &sched);
158         DES_ecb_encrypt((DES_cblock *) src, (DES_cblock *) dst,
159                         &sched, DES_ENCRYPT);
160
161         memset(&sched, 0, sizeof(sched));
162
163         return AFP_OK;
164 #endif /* HAVE_GCRYPT */
165 }