xsha1.c revision 35c4bbdf
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
3635c4bbdfSmrg#include <sha1.h>
376747b715Smrg
3835c4bbdfSmrgvoid *
3935c4bbdfSmrgx_sha1_init(void)
406747b715Smrg{
416747b715Smrg    SHA1_CTX *ctx = malloc(sizeof(*ctx));
4235c4bbdfSmrg
436747b715Smrg    if (!ctx)
446747b715Smrg        return NULL;
456747b715Smrg    SHA1Init(ctx);
466747b715Smrg    return ctx;
476747b715Smrg}
486747b715Smrg
4935c4bbdfSmrgint
5035c4bbdfSmrgx_sha1_update(void *ctx, void *data, int size)
516747b715Smrg{
526747b715Smrg    SHA1_CTX *sha1_ctx = ctx;
5335c4bbdfSmrg
546747b715Smrg    SHA1Update(sha1_ctx, data, size);
556747b715Smrg    return 1;
566747b715Smrg}
576747b715Smrg
5835c4bbdfSmrgint
5935c4bbdfSmrgx_sha1_final(void *ctx, unsigned char result[20])
606747b715Smrg{
616747b715Smrg    SHA1_CTX *sha1_ctx = ctx;
6235c4bbdfSmrg
636747b715Smrg    SHA1Final(result, sha1_ctx);
646747b715Smrg    free(sha1_ctx);
656747b715Smrg    return 1;
666747b715Smrg}
676747b715Smrg
6835c4bbdfSmrg#elif defined(HAVE_SHA1_IN_COMMONCRYPTO)        /* Use CommonCrypto for SHA1 */
696747b715Smrg
706747b715Smrg#include <CommonCrypto/CommonDigest.h>
716747b715Smrg
7235c4bbdfSmrgvoid *
7335c4bbdfSmrgx_sha1_init(void)
746747b715Smrg{
756747b715Smrg    CC_SHA1_CTX *ctx = malloc(sizeof(*ctx));
7635c4bbdfSmrg
776747b715Smrg    if (!ctx)
786747b715Smrg        return NULL;
796747b715Smrg    CC_SHA1_Init(ctx);
806747b715Smrg    return ctx;
816747b715Smrg}
826747b715Smrg
8335c4bbdfSmrgint
8435c4bbdfSmrgx_sha1_update(void *ctx, void *data, int size)
856747b715Smrg{
866747b715Smrg    CC_SHA1_CTX *sha1_ctx = ctx;
8735c4bbdfSmrg
886747b715Smrg    CC_SHA1_Update(sha1_ctx, data, size);
896747b715Smrg    return 1;
906747b715Smrg}
916747b715Smrg
9235c4bbdfSmrgint
9335c4bbdfSmrgx_sha1_final(void *ctx, unsigned char result[20])
946747b715Smrg{
956747b715Smrg    CC_SHA1_CTX *sha1_ctx = ctx;
9635c4bbdfSmrg
976747b715Smrg    CC_SHA1_Final(result, sha1_ctx);
986747b715Smrg    free(sha1_ctx);
996747b715Smrg    return 1;
1006747b715Smrg}
1016747b715Smrg
10235c4bbdfSmrg#elif defined(HAVE_SHA1_IN_CRYPTOAPI)        /* Use CryptoAPI for SHA1 */
1036747b715Smrg
10435c4bbdfSmrg#define WIN32_LEAN_AND_MEAN
10535c4bbdfSmrg#include <X11/Xwindows.h>
10635c4bbdfSmrg#include <wincrypt.h>
1076747b715Smrg
10835c4bbdfSmrgstatic HCRYPTPROV hProv;
10935c4bbdfSmrg
11035c4bbdfSmrgvoid *
11135c4bbdfSmrgx_sha1_init(void)
11235c4bbdfSmrg{
11335c4bbdfSmrg    HCRYPTHASH *ctx = malloc(sizeof(*ctx));
11435c4bbdfSmrg
11535c4bbdfSmrg    if (!ctx)
11635c4bbdfSmrg        return NULL;
11735c4bbdfSmrg    CryptAcquireContext(&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
11835c4bbdfSmrg    CryptCreateHash(hProv, CALG_SHA1, 0, 0, ctx);
11935c4bbdfSmrg    return ctx;
12035c4bbdfSmrg}
12135c4bbdfSmrg
12235c4bbdfSmrgint
12335c4bbdfSmrgx_sha1_update(void *ctx, void *data, int size)
12435c4bbdfSmrg{
12535c4bbdfSmrg    HCRYPTHASH *hHash = ctx;
12635c4bbdfSmrg
12735c4bbdfSmrg    CryptHashData(*hHash, data, size, 0);
12835c4bbdfSmrg    return 1;
12935c4bbdfSmrg}
13035c4bbdfSmrg
13135c4bbdfSmrgint
13235c4bbdfSmrgx_sha1_final(void *ctx, unsigned char result[20])
13335c4bbdfSmrg{
13435c4bbdfSmrg    HCRYPTHASH *hHash = ctx;
13535c4bbdfSmrg    DWORD len = 20;
13635c4bbdfSmrg
13735c4bbdfSmrg    CryptGetHashParam(*hHash, HP_HASHVAL, result, &len, 0);
13835c4bbdfSmrg    CryptDestroyHash(*hHash);
13935c4bbdfSmrg    CryptReleaseContext(hProv, 0);
14035c4bbdfSmrg    free(ctx);
14135c4bbdfSmrg    return 1;
14235c4bbdfSmrg}
14335c4bbdfSmrg
14435c4bbdfSmrg#elif defined(HAVE_SHA1_IN_LIBNETTLE)   /* Use libnettle for SHA1 */
14535c4bbdfSmrg
14635c4bbdfSmrg#include <nettle/sha.h>
14735c4bbdfSmrg
14835c4bbdfSmrgvoid *
14935c4bbdfSmrgx_sha1_init(void)
15035c4bbdfSmrg{
15135c4bbdfSmrg    struct sha1_ctx *ctx = malloc(sizeof(*ctx));
15235c4bbdfSmrg
15335c4bbdfSmrg    if (!ctx)
15435c4bbdfSmrg        return NULL;
15535c4bbdfSmrg    sha1_init(ctx);
15635c4bbdfSmrg    return ctx;
15735c4bbdfSmrg}
15835c4bbdfSmrg
15935c4bbdfSmrgint
16035c4bbdfSmrgx_sha1_update(void *ctx, void *data, int size)
16135c4bbdfSmrg{
16235c4bbdfSmrg    sha1_update(ctx, size, data);
16335c4bbdfSmrg    return 1;
16435c4bbdfSmrg}
16535c4bbdfSmrg
16635c4bbdfSmrgint
16735c4bbdfSmrgx_sha1_final(void *ctx, unsigned char result[20])
16835c4bbdfSmrg{
16935c4bbdfSmrg    sha1_digest(ctx, 20, result);
17035c4bbdfSmrg    free(ctx);
17135c4bbdfSmrg    return 1;
17235c4bbdfSmrg}
17335c4bbdfSmrg
17435c4bbdfSmrg#elif defined(HAVE_SHA1_IN_LIBGCRYPT)   /* Use libgcrypt for SHA1 */
17535c4bbdfSmrg
17635c4bbdfSmrg#include <gcrypt.h>
17735c4bbdfSmrg
17835c4bbdfSmrgvoid *
17935c4bbdfSmrgx_sha1_init(void)
1806747b715Smrg{
1816747b715Smrg    static int init;
1826747b715Smrg    gcry_md_hd_t h;
1836747b715Smrg    gcry_error_t err;
1846747b715Smrg
1856747b715Smrg    if (!init) {
1866747b715Smrg        if (!gcry_check_version(NULL))
1876747b715Smrg            return NULL;
1886747b715Smrg        gcry_control(GCRYCTL_DISABLE_SECMEM, 0);
1896747b715Smrg        gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0);
1906747b715Smrg        init = 1;
1916747b715Smrg    }
1926747b715Smrg
1936747b715Smrg    err = gcry_md_open(&h, GCRY_MD_SHA1, 0);
1946747b715Smrg    if (err)
1956747b715Smrg        return NULL;
1966747b715Smrg    return h;
1976747b715Smrg}
1986747b715Smrg
19935c4bbdfSmrgint
20035c4bbdfSmrgx_sha1_update(void *ctx, void *data, int size)
2016747b715Smrg{
2026747b715Smrg    gcry_md_hd_t h = ctx;
20335c4bbdfSmrg
2046747b715Smrg    gcry_md_write(h, data, size);
2056747b715Smrg    return 1;
2066747b715Smrg}
2076747b715Smrg
20835c4bbdfSmrgint
20935c4bbdfSmrgx_sha1_final(void *ctx, unsigned char result[20])
2106747b715Smrg{
2116747b715Smrg    gcry_md_hd_t h = ctx;
21235c4bbdfSmrg
2136747b715Smrg    memcpy(result, gcry_md_read(h, GCRY_MD_SHA1), 20);
2146747b715Smrg    gcry_md_close(h);
2156747b715Smrg    return 1;
2166747b715Smrg}
2176747b715Smrg
21835c4bbdfSmrg#elif defined(HAVE_SHA1_IN_LIBSHA1)     /* Use libsha1 */
2196747b715Smrg
22035c4bbdfSmrg#include <libsha1.h>
2216747b715Smrg
22235c4bbdfSmrgvoid *
22335c4bbdfSmrgx_sha1_init(void)
2246747b715Smrg{
2256747b715Smrg    sha1_ctx *ctx = malloc(sizeof(*ctx));
22635c4bbdfSmrg
22735c4bbdfSmrg    if (!ctx)
2286747b715Smrg        return NULL;
2296747b715Smrg    sha1_begin(ctx);
2306747b715Smrg    return ctx;
2316747b715Smrg}
2326747b715Smrg
23335c4bbdfSmrgint
23435c4bbdfSmrgx_sha1_update(void *ctx, void *data, int size)
2356747b715Smrg{
2366747b715Smrg    sha1_hash(data, size, ctx);
2376747b715Smrg    return 1;
2386747b715Smrg}
2396747b715Smrg
24035c4bbdfSmrgint
24135c4bbdfSmrgx_sha1_final(void *ctx, unsigned char result[20])
2426747b715Smrg{
2436747b715Smrg    sha1_end(result, ctx);
2446747b715Smrg    free(ctx);
2456747b715Smrg    return 1;
2466747b715Smrg}
2476747b715Smrg
24835c4bbdfSmrg#else                           /* Use OpenSSL's libcrypto */
2496747b715Smrg
25035c4bbdfSmrg#include <stddef.h>             /* buggy openssl/sha.h wants size_t */
25135c4bbdfSmrg#include <openssl/sha.h>
2526747b715Smrg
25335c4bbdfSmrgvoid *
25435c4bbdfSmrgx_sha1_init(void)
2556747b715Smrg{
2566747b715Smrg    int ret;
2576747b715Smrg    SHA_CTX *ctx = malloc(sizeof(*ctx));
25835c4bbdfSmrg
2596747b715Smrg    if (!ctx)
2606747b715Smrg        return NULL;
2616747b715Smrg    ret = SHA1_Init(ctx);
2626747b715Smrg    if (!ret) {
2636747b715Smrg        free(ctx);
2646747b715Smrg        return NULL;
2656747b715Smrg    }
2666747b715Smrg    return ctx;
2676747b715Smrg}
2686747b715Smrg
26935c4bbdfSmrgint
27035c4bbdfSmrgx_sha1_update(void *ctx, void *data, int size)
2716747b715Smrg{
2726747b715Smrg    int ret;
2736747b715Smrg    SHA_CTX *sha_ctx = ctx;
27435c4bbdfSmrg
2756747b715Smrg    ret = SHA1_Update(sha_ctx, data, size);
2766747b715Smrg    if (!ret)
2776747b715Smrg        free(sha_ctx);
2786747b715Smrg    return ret;
2796747b715Smrg}
2806747b715Smrg
28135c4bbdfSmrgint
28235c4bbdfSmrgx_sha1_final(void *ctx, unsigned char result[20])
2836747b715Smrg{
2846747b715Smrg    int ret;
2856747b715Smrg    SHA_CTX *sha_ctx = ctx;
28635c4bbdfSmrg
2876747b715Smrg    ret = SHA1_Final(result, sha_ctx);
2886747b715Smrg    free(sha_ctx);
2896747b715Smrg    return ret;
2906747b715Smrg}
2916747b715Smrg
2926747b715Smrg#endif
293