1*4882a593Smuzhiyun /* Copyright © 2007 Carl Worth
2*4882a593Smuzhiyun * Copyright © 2009 Jeremy Huddleston, Julien Cristau, and Matthieu Herrb
3*4882a593Smuzhiyun * Copyright © 2009-2010 Mikhail Gusarov
4*4882a593Smuzhiyun * Copyright © 2012 Yaakov Selkowitz and Keith Packard
5*4882a593Smuzhiyun *
6*4882a593Smuzhiyun * Permission is hereby granted, free of charge, to any person obtaining a
7*4882a593Smuzhiyun * copy of this software and associated documentation files (the "Software"),
8*4882a593Smuzhiyun * to deal in the Software without restriction, including without limitation
9*4882a593Smuzhiyun * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10*4882a593Smuzhiyun * and/or sell copies of the Software, and to permit persons to whom the
11*4882a593Smuzhiyun * Software is furnished to do so, subject to the following conditions:
12*4882a593Smuzhiyun *
13*4882a593Smuzhiyun * The above copyright notice and this permission notice (including the next
14*4882a593Smuzhiyun * paragraph) shall be included in all copies or substantial portions of the
15*4882a593Smuzhiyun * Software.
16*4882a593Smuzhiyun *
17*4882a593Smuzhiyun * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18*4882a593Smuzhiyun * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19*4882a593Smuzhiyun * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20*4882a593Smuzhiyun * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21*4882a593Smuzhiyun * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22*4882a593Smuzhiyun * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23*4882a593Smuzhiyun * DEALINGS IN THE SOFTWARE.
24*4882a593Smuzhiyun */
25*4882a593Smuzhiyun
26*4882a593Smuzhiyun #ifdef HAVE_DIX_CONFIG_H
27*4882a593Smuzhiyun #include <dix-config.h>
28*4882a593Smuzhiyun #endif
29*4882a593Smuzhiyun
30*4882a593Smuzhiyun #include "os.h"
31*4882a593Smuzhiyun #include "xsha1.h"
32*4882a593Smuzhiyun
33*4882a593Smuzhiyun #if defined(HAVE_SHA1_IN_LIBMD) /* Use libmd for SHA1 */ \
34*4882a593Smuzhiyun || defined(HAVE_SHA1_IN_LIBC) /* Use libc for SHA1 */
35*4882a593Smuzhiyun
36*4882a593Smuzhiyun #include <sha1.h>
37*4882a593Smuzhiyun
38*4882a593Smuzhiyun void *
x_sha1_init(void)39*4882a593Smuzhiyun x_sha1_init(void)
40*4882a593Smuzhiyun {
41*4882a593Smuzhiyun SHA1_CTX *ctx = malloc(sizeof(*ctx));
42*4882a593Smuzhiyun
43*4882a593Smuzhiyun if (!ctx)
44*4882a593Smuzhiyun return NULL;
45*4882a593Smuzhiyun SHA1Init(ctx);
46*4882a593Smuzhiyun return ctx;
47*4882a593Smuzhiyun }
48*4882a593Smuzhiyun
49*4882a593Smuzhiyun int
x_sha1_update(void * ctx,void * data,int size)50*4882a593Smuzhiyun x_sha1_update(void *ctx, void *data, int size)
51*4882a593Smuzhiyun {
52*4882a593Smuzhiyun SHA1_CTX *sha1_ctx = ctx;
53*4882a593Smuzhiyun
54*4882a593Smuzhiyun SHA1Update(sha1_ctx, data, size);
55*4882a593Smuzhiyun return 1;
56*4882a593Smuzhiyun }
57*4882a593Smuzhiyun
58*4882a593Smuzhiyun int
x_sha1_final(void * ctx,unsigned char result[20])59*4882a593Smuzhiyun x_sha1_final(void *ctx, unsigned char result[20])
60*4882a593Smuzhiyun {
61*4882a593Smuzhiyun SHA1_CTX *sha1_ctx = ctx;
62*4882a593Smuzhiyun
63*4882a593Smuzhiyun SHA1Final(result, sha1_ctx);
64*4882a593Smuzhiyun free(sha1_ctx);
65*4882a593Smuzhiyun return 1;
66*4882a593Smuzhiyun }
67*4882a593Smuzhiyun
68*4882a593Smuzhiyun #elif defined(HAVE_SHA1_IN_COMMONCRYPTO) /* Use CommonCrypto for SHA1 */
69*4882a593Smuzhiyun
70*4882a593Smuzhiyun #include <CommonCrypto/CommonDigest.h>
71*4882a593Smuzhiyun
72*4882a593Smuzhiyun void *
x_sha1_init(void)73*4882a593Smuzhiyun x_sha1_init(void)
74*4882a593Smuzhiyun {
75*4882a593Smuzhiyun CC_SHA1_CTX *ctx = malloc(sizeof(*ctx));
76*4882a593Smuzhiyun
77*4882a593Smuzhiyun if (!ctx)
78*4882a593Smuzhiyun return NULL;
79*4882a593Smuzhiyun CC_SHA1_Init(ctx);
80*4882a593Smuzhiyun return ctx;
81*4882a593Smuzhiyun }
82*4882a593Smuzhiyun
83*4882a593Smuzhiyun int
x_sha1_update(void * ctx,void * data,int size)84*4882a593Smuzhiyun x_sha1_update(void *ctx, void *data, int size)
85*4882a593Smuzhiyun {
86*4882a593Smuzhiyun CC_SHA1_CTX *sha1_ctx = ctx;
87*4882a593Smuzhiyun
88*4882a593Smuzhiyun CC_SHA1_Update(sha1_ctx, data, size);
89*4882a593Smuzhiyun return 1;
90*4882a593Smuzhiyun }
91*4882a593Smuzhiyun
92*4882a593Smuzhiyun int
x_sha1_final(void * ctx,unsigned char result[20])93*4882a593Smuzhiyun x_sha1_final(void *ctx, unsigned char result[20])
94*4882a593Smuzhiyun {
95*4882a593Smuzhiyun CC_SHA1_CTX *sha1_ctx = ctx;
96*4882a593Smuzhiyun
97*4882a593Smuzhiyun CC_SHA1_Final(result, sha1_ctx);
98*4882a593Smuzhiyun free(sha1_ctx);
99*4882a593Smuzhiyun return 1;
100*4882a593Smuzhiyun }
101*4882a593Smuzhiyun
102*4882a593Smuzhiyun #elif defined(HAVE_SHA1_IN_CRYPTOAPI) /* Use CryptoAPI for SHA1 */
103*4882a593Smuzhiyun
104*4882a593Smuzhiyun #define WIN32_LEAN_AND_MEAN
105*4882a593Smuzhiyun #include <X11/Xwindows.h>
106*4882a593Smuzhiyun #include <wincrypt.h>
107*4882a593Smuzhiyun
108*4882a593Smuzhiyun static HCRYPTPROV hProv;
109*4882a593Smuzhiyun
110*4882a593Smuzhiyun void *
x_sha1_init(void)111*4882a593Smuzhiyun x_sha1_init(void)
112*4882a593Smuzhiyun {
113*4882a593Smuzhiyun HCRYPTHASH *ctx = malloc(sizeof(*ctx));
114*4882a593Smuzhiyun
115*4882a593Smuzhiyun if (!ctx)
116*4882a593Smuzhiyun return NULL;
117*4882a593Smuzhiyun CryptAcquireContext(&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
118*4882a593Smuzhiyun CryptCreateHash(hProv, CALG_SHA1, 0, 0, ctx);
119*4882a593Smuzhiyun return ctx;
120*4882a593Smuzhiyun }
121*4882a593Smuzhiyun
122*4882a593Smuzhiyun int
x_sha1_update(void * ctx,void * data,int size)123*4882a593Smuzhiyun x_sha1_update(void *ctx, void *data, int size)
124*4882a593Smuzhiyun {
125*4882a593Smuzhiyun HCRYPTHASH *hHash = ctx;
126*4882a593Smuzhiyun
127*4882a593Smuzhiyun CryptHashData(*hHash, data, size, 0);
128*4882a593Smuzhiyun return 1;
129*4882a593Smuzhiyun }
130*4882a593Smuzhiyun
131*4882a593Smuzhiyun int
x_sha1_final(void * ctx,unsigned char result[20])132*4882a593Smuzhiyun x_sha1_final(void *ctx, unsigned char result[20])
133*4882a593Smuzhiyun {
134*4882a593Smuzhiyun HCRYPTHASH *hHash = ctx;
135*4882a593Smuzhiyun DWORD len = 20;
136*4882a593Smuzhiyun
137*4882a593Smuzhiyun CryptGetHashParam(*hHash, HP_HASHVAL, result, &len, 0);
138*4882a593Smuzhiyun CryptDestroyHash(*hHash);
139*4882a593Smuzhiyun CryptReleaseContext(hProv, 0);
140*4882a593Smuzhiyun free(ctx);
141*4882a593Smuzhiyun return 1;
142*4882a593Smuzhiyun }
143*4882a593Smuzhiyun
144*4882a593Smuzhiyun #elif defined(HAVE_SHA1_IN_LIBNETTLE) /* Use libnettle for SHA1 */
145*4882a593Smuzhiyun
146*4882a593Smuzhiyun #include <nettle/sha.h>
147*4882a593Smuzhiyun
148*4882a593Smuzhiyun void *
x_sha1_init(void)149*4882a593Smuzhiyun x_sha1_init(void)
150*4882a593Smuzhiyun {
151*4882a593Smuzhiyun struct sha1_ctx *ctx = malloc(sizeof(*ctx));
152*4882a593Smuzhiyun
153*4882a593Smuzhiyun if (!ctx)
154*4882a593Smuzhiyun return NULL;
155*4882a593Smuzhiyun sha1_init(ctx);
156*4882a593Smuzhiyun return ctx;
157*4882a593Smuzhiyun }
158*4882a593Smuzhiyun
159*4882a593Smuzhiyun int
x_sha1_update(void * ctx,void * data,int size)160*4882a593Smuzhiyun x_sha1_update(void *ctx, void *data, int size)
161*4882a593Smuzhiyun {
162*4882a593Smuzhiyun sha1_update(ctx, size, data);
163*4882a593Smuzhiyun return 1;
164*4882a593Smuzhiyun }
165*4882a593Smuzhiyun
166*4882a593Smuzhiyun int
x_sha1_final(void * ctx,unsigned char result[20])167*4882a593Smuzhiyun x_sha1_final(void *ctx, unsigned char result[20])
168*4882a593Smuzhiyun {
169*4882a593Smuzhiyun sha1_digest(ctx, 20, result);
170*4882a593Smuzhiyun free(ctx);
171*4882a593Smuzhiyun return 1;
172*4882a593Smuzhiyun }
173*4882a593Smuzhiyun
174*4882a593Smuzhiyun #elif defined(HAVE_SHA1_IN_LIBGCRYPT) /* Use libgcrypt for SHA1 */
175*4882a593Smuzhiyun
176*4882a593Smuzhiyun #include <gcrypt.h>
177*4882a593Smuzhiyun
178*4882a593Smuzhiyun void *
x_sha1_init(void)179*4882a593Smuzhiyun x_sha1_init(void)
180*4882a593Smuzhiyun {
181*4882a593Smuzhiyun static int init;
182*4882a593Smuzhiyun gcry_md_hd_t h;
183*4882a593Smuzhiyun gcry_error_t err;
184*4882a593Smuzhiyun
185*4882a593Smuzhiyun if (!init) {
186*4882a593Smuzhiyun if (!gcry_check_version(NULL))
187*4882a593Smuzhiyun return NULL;
188*4882a593Smuzhiyun gcry_control(GCRYCTL_DISABLE_SECMEM, 0);
189*4882a593Smuzhiyun gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0);
190*4882a593Smuzhiyun init = 1;
191*4882a593Smuzhiyun }
192*4882a593Smuzhiyun
193*4882a593Smuzhiyun err = gcry_md_open(&h, GCRY_MD_SHA1, 0);
194*4882a593Smuzhiyun if (err)
195*4882a593Smuzhiyun return NULL;
196*4882a593Smuzhiyun return h;
197*4882a593Smuzhiyun }
198*4882a593Smuzhiyun
199*4882a593Smuzhiyun int
x_sha1_update(void * ctx,void * data,int size)200*4882a593Smuzhiyun x_sha1_update(void *ctx, void *data, int size)
201*4882a593Smuzhiyun {
202*4882a593Smuzhiyun gcry_md_hd_t h = ctx;
203*4882a593Smuzhiyun
204*4882a593Smuzhiyun gcry_md_write(h, data, size);
205*4882a593Smuzhiyun return 1;
206*4882a593Smuzhiyun }
207*4882a593Smuzhiyun
208*4882a593Smuzhiyun int
x_sha1_final(void * ctx,unsigned char result[20])209*4882a593Smuzhiyun x_sha1_final(void *ctx, unsigned char result[20])
210*4882a593Smuzhiyun {
211*4882a593Smuzhiyun gcry_md_hd_t h = ctx;
212*4882a593Smuzhiyun
213*4882a593Smuzhiyun memcpy(result, gcry_md_read(h, GCRY_MD_SHA1), 20);
214*4882a593Smuzhiyun gcry_md_close(h);
215*4882a593Smuzhiyun return 1;
216*4882a593Smuzhiyun }
217*4882a593Smuzhiyun
218*4882a593Smuzhiyun #elif defined(HAVE_SHA1_IN_LIBSHA1) /* Use libsha1 */
219*4882a593Smuzhiyun
220*4882a593Smuzhiyun #include <libsha1.h>
221*4882a593Smuzhiyun
222*4882a593Smuzhiyun void *
x_sha1_init(void)223*4882a593Smuzhiyun x_sha1_init(void)
224*4882a593Smuzhiyun {
225*4882a593Smuzhiyun sha1_ctx *ctx = malloc(sizeof(*ctx));
226*4882a593Smuzhiyun
227*4882a593Smuzhiyun if (!ctx)
228*4882a593Smuzhiyun return NULL;
229*4882a593Smuzhiyun sha1_begin(ctx);
230*4882a593Smuzhiyun return ctx;
231*4882a593Smuzhiyun }
232*4882a593Smuzhiyun
233*4882a593Smuzhiyun int
x_sha1_update(void * ctx,void * data,int size)234*4882a593Smuzhiyun x_sha1_update(void *ctx, void *data, int size)
235*4882a593Smuzhiyun {
236*4882a593Smuzhiyun sha1_hash(data, size, ctx);
237*4882a593Smuzhiyun return 1;
238*4882a593Smuzhiyun }
239*4882a593Smuzhiyun
240*4882a593Smuzhiyun int
x_sha1_final(void * ctx,unsigned char result[20])241*4882a593Smuzhiyun x_sha1_final(void *ctx, unsigned char result[20])
242*4882a593Smuzhiyun {
243*4882a593Smuzhiyun sha1_end(result, ctx);
244*4882a593Smuzhiyun free(ctx);
245*4882a593Smuzhiyun return 1;
246*4882a593Smuzhiyun }
247*4882a593Smuzhiyun
248*4882a593Smuzhiyun #else /* Use OpenSSL's libcrypto */
249*4882a593Smuzhiyun
250*4882a593Smuzhiyun #include <stddef.h> /* buggy openssl/sha.h wants size_t */
251*4882a593Smuzhiyun #include <openssl/sha.h>
252*4882a593Smuzhiyun
253*4882a593Smuzhiyun void *
x_sha1_init(void)254*4882a593Smuzhiyun x_sha1_init(void)
255*4882a593Smuzhiyun {
256*4882a593Smuzhiyun int ret;
257*4882a593Smuzhiyun SHA_CTX *ctx = malloc(sizeof(*ctx));
258*4882a593Smuzhiyun
259*4882a593Smuzhiyun if (!ctx)
260*4882a593Smuzhiyun return NULL;
261*4882a593Smuzhiyun ret = SHA1_Init(ctx);
262*4882a593Smuzhiyun if (!ret) {
263*4882a593Smuzhiyun free(ctx);
264*4882a593Smuzhiyun return NULL;
265*4882a593Smuzhiyun }
266*4882a593Smuzhiyun return ctx;
267*4882a593Smuzhiyun }
268*4882a593Smuzhiyun
269*4882a593Smuzhiyun int
x_sha1_update(void * ctx,void * data,int size)270*4882a593Smuzhiyun x_sha1_update(void *ctx, void *data, int size)
271*4882a593Smuzhiyun {
272*4882a593Smuzhiyun int ret;
273*4882a593Smuzhiyun SHA_CTX *sha_ctx = ctx;
274*4882a593Smuzhiyun
275*4882a593Smuzhiyun ret = SHA1_Update(sha_ctx, data, size);
276*4882a593Smuzhiyun if (!ret)
277*4882a593Smuzhiyun free(sha_ctx);
278*4882a593Smuzhiyun return ret;
279*4882a593Smuzhiyun }
280*4882a593Smuzhiyun
281*4882a593Smuzhiyun int
x_sha1_final(void * ctx,unsigned char result[20])282*4882a593Smuzhiyun x_sha1_final(void *ctx, unsigned char result[20])
283*4882a593Smuzhiyun {
284*4882a593Smuzhiyun int ret;
285*4882a593Smuzhiyun SHA_CTX *sha_ctx = ctx;
286*4882a593Smuzhiyun
287*4882a593Smuzhiyun ret = SHA1_Final(result, sha_ctx);
288*4882a593Smuzhiyun free(sha_ctx);
289*4882a593Smuzhiyun return ret;
290*4882a593Smuzhiyun }
291*4882a593Smuzhiyun
292*4882a593Smuzhiyun #endif
293