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