135c4bbdfSmrg/* Copyright © 2007 Carl Worth
235c4bbdfSmrg * Copyright © 2009 Jeremy Huddleston, Julien Cristau, and Matthieu Herrb
335c4bbdfSmrg * Copyright © 2009-2010 Mikhail Gusarov
435c4bbdfSmrg * Copyright © 2012 Yaakov Selkowitz and Keith Packard
535c4bbdfSmrg *
635c4bbdfSmrg * Permission is hereby granted, free of charge, to any person obtaining a
735c4bbdfSmrg * copy of this software and associated documentation files (the "Software"),
835c4bbdfSmrg * to deal in the Software without restriction, including without limitation
935c4bbdfSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
1035c4bbdfSmrg * and/or sell copies of the Software, and to permit persons to whom the
1135c4bbdfSmrg * Software is furnished to do so, subject to the following conditions:
1235c4bbdfSmrg *
1335c4bbdfSmrg * The above copyright notice and this permission notice (including the next
1435c4bbdfSmrg * paragraph) shall be included in all copies or substantial portions of the
1535c4bbdfSmrg * Software.
1635c4bbdfSmrg *
1735c4bbdfSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1835c4bbdfSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1935c4bbdfSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
2035c4bbdfSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2135c4bbdfSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
2235c4bbdfSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
2335c4bbdfSmrg * DEALINGS IN THE SOFTWARE.
2435c4bbdfSmrg */
2535c4bbdfSmrg
266747b715Smrg#ifdef HAVE_DIX_CONFIG_H
276747b715Smrg#include <dix-config.h>
286747b715Smrg#endif
296747b715Smrg
306747b715Smrg#include "os.h"
316747b715Smrg#include "xsha1.h"
326747b715Smrg
336747b715Smrg#if defined(HAVE_SHA1_IN_LIBMD)  /* Use libmd for SHA1 */ \
3435c4bbdfSmrg	|| defined(HAVE_SHA1_IN_LIBC)   /* Use libc for SHA1 */
356747b715Smrg
36ed6184dfSmrg#if defined(__DragonFly__) || defined(__FreeBSD__)
37ed6184dfSmrg#include <sha.h>
38ed6184dfSmrg#define	SHA1End		SHA1_End
39ed6184dfSmrg#define	SHA1File	SHA1_File
40ed6184dfSmrg#define	SHA1Final	SHA1_Final
41ed6184dfSmrg#define	SHA1Init	SHA1_Init
42ed6184dfSmrg#define	SHA1Update	SHA1_Update
43ed6184dfSmrg#else
4435c4bbdfSmrg#include <sha1.h>
45ed6184dfSmrg#endif
466747b715Smrg
4735c4bbdfSmrgvoid *
4835c4bbdfSmrgx_sha1_init(void)
496747b715Smrg{
506747b715Smrg    SHA1_CTX *ctx = malloc(sizeof(*ctx));
5135c4bbdfSmrg
526747b715Smrg    if (!ctx)
536747b715Smrg        return NULL;
546747b715Smrg    SHA1Init(ctx);
556747b715Smrg    return ctx;
566747b715Smrg}
576747b715Smrg
5835c4bbdfSmrgint
5935c4bbdfSmrgx_sha1_update(void *ctx, void *data, int size)
606747b715Smrg{
616747b715Smrg    SHA1_CTX *sha1_ctx = ctx;
6235c4bbdfSmrg
636747b715Smrg    SHA1Update(sha1_ctx, data, size);
646747b715Smrg    return 1;
656747b715Smrg}
666747b715Smrg
6735c4bbdfSmrgint
6835c4bbdfSmrgx_sha1_final(void *ctx, unsigned char result[20])
696747b715Smrg{
706747b715Smrg    SHA1_CTX *sha1_ctx = ctx;
7135c4bbdfSmrg
726747b715Smrg    SHA1Final(result, sha1_ctx);
736747b715Smrg    free(sha1_ctx);
746747b715Smrg    return 1;
756747b715Smrg}
766747b715Smrg
7735c4bbdfSmrg#elif defined(HAVE_SHA1_IN_COMMONCRYPTO)        /* Use CommonCrypto for SHA1 */
786747b715Smrg
796747b715Smrg#include <CommonCrypto/CommonDigest.h>
806747b715Smrg
8135c4bbdfSmrgvoid *
8235c4bbdfSmrgx_sha1_init(void)
836747b715Smrg{
846747b715Smrg    CC_SHA1_CTX *ctx = malloc(sizeof(*ctx));
8535c4bbdfSmrg
866747b715Smrg    if (!ctx)
876747b715Smrg        return NULL;
886747b715Smrg    CC_SHA1_Init(ctx);
896747b715Smrg    return ctx;
906747b715Smrg}
916747b715Smrg
9235c4bbdfSmrgint
9335c4bbdfSmrgx_sha1_update(void *ctx, void *data, int size)
946747b715Smrg{
956747b715Smrg    CC_SHA1_CTX *sha1_ctx = ctx;
9635c4bbdfSmrg
976747b715Smrg    CC_SHA1_Update(sha1_ctx, data, size);
986747b715Smrg    return 1;
996747b715Smrg}
1006747b715Smrg
10135c4bbdfSmrgint
10235c4bbdfSmrgx_sha1_final(void *ctx, unsigned char result[20])
1036747b715Smrg{
1046747b715Smrg    CC_SHA1_CTX *sha1_ctx = ctx;
10535c4bbdfSmrg
1066747b715Smrg    CC_SHA1_Final(result, sha1_ctx);
1076747b715Smrg    free(sha1_ctx);
1086747b715Smrg    return 1;
1096747b715Smrg}
1106747b715Smrg
11135c4bbdfSmrg#elif defined(HAVE_SHA1_IN_CRYPTOAPI)        /* Use CryptoAPI for SHA1 */
1126747b715Smrg
11335c4bbdfSmrg#define WIN32_LEAN_AND_MEAN
11435c4bbdfSmrg#include <X11/Xwindows.h>
11535c4bbdfSmrg#include <wincrypt.h>
1166747b715Smrg
11735c4bbdfSmrgstatic HCRYPTPROV hProv;
11835c4bbdfSmrg
11935c4bbdfSmrgvoid *
12035c4bbdfSmrgx_sha1_init(void)
12135c4bbdfSmrg{
12235c4bbdfSmrg    HCRYPTHASH *ctx = malloc(sizeof(*ctx));
12335c4bbdfSmrg
12435c4bbdfSmrg    if (!ctx)
12535c4bbdfSmrg        return NULL;
12635c4bbdfSmrg    CryptAcquireContext(&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
12735c4bbdfSmrg    CryptCreateHash(hProv, CALG_SHA1, 0, 0, ctx);
12835c4bbdfSmrg    return ctx;
12935c4bbdfSmrg}
13035c4bbdfSmrg
13135c4bbdfSmrgint
13235c4bbdfSmrgx_sha1_update(void *ctx, void *data, int size)
13335c4bbdfSmrg{
13435c4bbdfSmrg    HCRYPTHASH *hHash = ctx;
13535c4bbdfSmrg
13635c4bbdfSmrg    CryptHashData(*hHash, data, size, 0);
13735c4bbdfSmrg    return 1;
13835c4bbdfSmrg}
13935c4bbdfSmrg
14035c4bbdfSmrgint
14135c4bbdfSmrgx_sha1_final(void *ctx, unsigned char result[20])
14235c4bbdfSmrg{
14335c4bbdfSmrg    HCRYPTHASH *hHash = ctx;
14435c4bbdfSmrg    DWORD len = 20;
14535c4bbdfSmrg
14635c4bbdfSmrg    CryptGetHashParam(*hHash, HP_HASHVAL, result, &len, 0);
14735c4bbdfSmrg    CryptDestroyHash(*hHash);
14835c4bbdfSmrg    CryptReleaseContext(hProv, 0);
14935c4bbdfSmrg    free(ctx);
15035c4bbdfSmrg    return 1;
15135c4bbdfSmrg}
15235c4bbdfSmrg
15335c4bbdfSmrg#elif defined(HAVE_SHA1_IN_LIBNETTLE)   /* Use libnettle for SHA1 */
15435c4bbdfSmrg
15535c4bbdfSmrg#include <nettle/sha.h>
15635c4bbdfSmrg
15735c4bbdfSmrgvoid *
15835c4bbdfSmrgx_sha1_init(void)
15935c4bbdfSmrg{
16035c4bbdfSmrg    struct sha1_ctx *ctx = malloc(sizeof(*ctx));
16135c4bbdfSmrg
16235c4bbdfSmrg    if (!ctx)
16335c4bbdfSmrg        return NULL;
16435c4bbdfSmrg    sha1_init(ctx);
16535c4bbdfSmrg    return ctx;
16635c4bbdfSmrg}
16735c4bbdfSmrg
16835c4bbdfSmrgint
16935c4bbdfSmrgx_sha1_update(void *ctx, void *data, int size)
17035c4bbdfSmrg{
17135c4bbdfSmrg    sha1_update(ctx, size, data);
17235c4bbdfSmrg    return 1;
17335c4bbdfSmrg}
17435c4bbdfSmrg
17535c4bbdfSmrgint
17635c4bbdfSmrgx_sha1_final(void *ctx, unsigned char result[20])
17735c4bbdfSmrg{
17835c4bbdfSmrg    sha1_digest(ctx, 20, result);
17935c4bbdfSmrg    free(ctx);
18035c4bbdfSmrg    return 1;
18135c4bbdfSmrg}
18235c4bbdfSmrg
18335c4bbdfSmrg#elif defined(HAVE_SHA1_IN_LIBGCRYPT)   /* Use libgcrypt for SHA1 */
18435c4bbdfSmrg
18535c4bbdfSmrg#include <gcrypt.h>
18635c4bbdfSmrg
18735c4bbdfSmrgvoid *
18835c4bbdfSmrgx_sha1_init(void)
1896747b715Smrg{
1906747b715Smrg    static int init;
1916747b715Smrg    gcry_md_hd_t h;
1926747b715Smrg    gcry_error_t err;
1936747b715Smrg
1946747b715Smrg    if (!init) {
1956747b715Smrg        if (!gcry_check_version(NULL))
1966747b715Smrg            return NULL;
1976747b715Smrg        gcry_control(GCRYCTL_DISABLE_SECMEM, 0);
1986747b715Smrg        gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0);
1996747b715Smrg        init = 1;
2006747b715Smrg    }
2016747b715Smrg
2026747b715Smrg    err = gcry_md_open(&h, GCRY_MD_SHA1, 0);
2036747b715Smrg    if (err)
2046747b715Smrg        return NULL;
2056747b715Smrg    return h;
2066747b715Smrg}
2076747b715Smrg
20835c4bbdfSmrgint
20935c4bbdfSmrgx_sha1_update(void *ctx, void *data, int size)
2106747b715Smrg{
2116747b715Smrg    gcry_md_hd_t h = ctx;
21235c4bbdfSmrg
2136747b715Smrg    gcry_md_write(h, data, size);
2146747b715Smrg    return 1;
2156747b715Smrg}
2166747b715Smrg
21735c4bbdfSmrgint
21835c4bbdfSmrgx_sha1_final(void *ctx, unsigned char result[20])
2196747b715Smrg{
2206747b715Smrg    gcry_md_hd_t h = ctx;
22135c4bbdfSmrg
2226747b715Smrg    memcpy(result, gcry_md_read(h, GCRY_MD_SHA1), 20);
2236747b715Smrg    gcry_md_close(h);
2246747b715Smrg    return 1;
2256747b715Smrg}
2266747b715Smrg
22735c4bbdfSmrg#elif defined(HAVE_SHA1_IN_LIBSHA1)     /* Use libsha1 */
2286747b715Smrg
22935c4bbdfSmrg#include <libsha1.h>
2306747b715Smrg
23135c4bbdfSmrgvoid *
23235c4bbdfSmrgx_sha1_init(void)
2336747b715Smrg{
2346747b715Smrg    sha1_ctx *ctx = malloc(sizeof(*ctx));
23535c4bbdfSmrg
23635c4bbdfSmrg    if (!ctx)
2376747b715Smrg        return NULL;
2386747b715Smrg    sha1_begin(ctx);
2396747b715Smrg    return ctx;
2406747b715Smrg}
2416747b715Smrg
24235c4bbdfSmrgint
24335c4bbdfSmrgx_sha1_update(void *ctx, void *data, int size)
2446747b715Smrg{
2456747b715Smrg    sha1_hash(data, size, ctx);
2466747b715Smrg    return 1;
2476747b715Smrg}
2486747b715Smrg
24935c4bbdfSmrgint
25035c4bbdfSmrgx_sha1_final(void *ctx, unsigned char result[20])
2516747b715Smrg{
2526747b715Smrg    sha1_end(result, ctx);
2536747b715Smrg    free(ctx);
2546747b715Smrg    return 1;
2556747b715Smrg}
2566747b715Smrg
25735c4bbdfSmrg#else                           /* Use OpenSSL's libcrypto */
2586747b715Smrg
25935c4bbdfSmrg#include <stddef.h>             /* buggy openssl/sha.h wants size_t */
26035c4bbdfSmrg#include <openssl/sha.h>
2616747b715Smrg
26235c4bbdfSmrgvoid *
26335c4bbdfSmrgx_sha1_init(void)
2646747b715Smrg{
2656747b715Smrg    int ret;
2666747b715Smrg    SHA_CTX *ctx = malloc(sizeof(*ctx));
26735c4bbdfSmrg
2686747b715Smrg    if (!ctx)
2696747b715Smrg        return NULL;
2706747b715Smrg    ret = SHA1_Init(ctx);
2716747b715Smrg    if (!ret) {
2726747b715Smrg        free(ctx);
2736747b715Smrg        return NULL;
2746747b715Smrg    }
2756747b715Smrg    return ctx;
2766747b715Smrg}
2776747b715Smrg
27835c4bbdfSmrgint
27935c4bbdfSmrgx_sha1_update(void *ctx, void *data, int size)
2806747b715Smrg{
2816747b715Smrg    int ret;
2826747b715Smrg    SHA_CTX *sha_ctx = ctx;
28335c4bbdfSmrg
2846747b715Smrg    ret = SHA1_Update(sha_ctx, data, size);
2856747b715Smrg    if (!ret)
2866747b715Smrg        free(sha_ctx);
2876747b715Smrg    return ret;
2886747b715Smrg}
2896747b715Smrg
29035c4bbdfSmrgint
29135c4bbdfSmrgx_sha1_final(void *ctx, unsigned char result[20])
2926747b715Smrg{
2936747b715Smrg    int ret;
2946747b715Smrg    SHA_CTX *sha_ctx = ctx;
29535c4bbdfSmrg
2966747b715Smrg    ret = SHA1_Final(result, sha_ctx);
2976747b715Smrg    free(sha_ctx);
2986747b715Smrg    return ret;
2996747b715Smrg}
3006747b715Smrg
3016747b715Smrg#endif
302