diff options
-rw-r--r-- | configure.ac | 25 | ||||
-rw-r--r-- | include/dix-config.h.in | 3 | ||||
-rw-r--r-- | render/Makefile.am | 3 | ||||
-rw-r--r-- | render/glyph.c | 29 | ||||
-rw-r--r-- | render/sha1.c | 173 | ||||
-rw-r--r-- | render/sha1.h | 63 |
6 files changed, 54 insertions, 242 deletions
diff --git a/configure.ac b/configure.ac index 278d33b61..60cdc144a 100644 --- a/configure.ac +++ b/configure.ac @@ -1072,6 +1072,27 @@ MIEXT_SHADOW_INC='-I$(top_srcdir)/miext/shadow' MIEXT_SHADOW_LIB='$(top_builddir)/miext/shadow/libshadow.la' CORE_INCS='-I$(top_srcdir)/include -I$(top_builddir)/include' +# OpenSSL used for SHA1 hashing in render/glyph.c, but we don't need all of +# the OpenSSL libraries, just libcrypto +# Some systems have matching functionality in the smaller/simpler libmd +# Builders who want to force a choice can set SHA1_LIB and SHA1_CFLAGS +if test "x$SHA1_LIB" = "x" ; then + AC_CHECK_LIB([md], [SHA1Init], [SHA1_LIB="-lmd" + AC_DEFINE([HAVE_SHA1_IN_LIBMD], [1], + [Use libmd SHA1 functions instead of OpenSSL libcrypto])]) +fi + +if test "x$SHA1_LIB" = "x" ; then + PKG_CHECK_EXISTS([OPENSSL], [openssl], [HAVE_OPENSSL_PKC=yes], + [HAVE_OPENSSL_PKC=no]) + if test "x$HAVE_OPENSSL_PKC" = xyes; then + REQUIRED_LIBS="$REQUIRED_LIBS openssl" + else + AC_CHECK_LIB([crypto], [SHA1_Init], [SHA1_LIB="-lcrypto"], + [AC_MSG_ERROR([OpenSSL must be installed in order to build the X server.])]) + fi +fi + PKG_CHECK_MODULES([XSERVERCFLAGS], [$REQUIRED_MODULES $REQUIRED_LIBS]) PKG_CHECK_MODULES([XSERVERLIBS], [$REQUIRED_LIBS]) @@ -1090,9 +1111,9 @@ PKG_CHECK_MODULES([XSERVERLIBS], [$REQUIRED_LIBS]) # XSERVER_SYS_LIBS is the set of out-of-tree libraries which all servers # require. # -XSERVER_CFLAGS="${XSERVERCFLAGS_CFLAGS}" +XSERVER_CFLAGS="${XSERVERCFLAGS_CFLAGS} ${SHA1_CFLAGS}" XSERVER_LIBS="$DIX_LIB $CONFIG_LIB $MI_LIB $OS_LIB" -XSERVER_SYS_LIBS="${XSERVERLIBS_LIBS} ${SYS_LIBS} ${LIBS}" +XSERVER_SYS_LIBS="${XSERVERLIBS_LIBS} ${SYS_LIBS} ${LIBS} ${SHA1_LIB}" AC_SUBST([XSERVER_LIBS]) AC_SUBST([XSERVER_SYS_LIBS]) diff --git a/include/dix-config.h.in b/include/dix-config.h.in index 3affc8a60..06138c5db 100644 --- a/include/dix-config.h.in +++ b/include/dix-config.h.in @@ -145,6 +145,9 @@ /* Define to 1 if you have the <rpcsvc/dbm.h> header file. */ #undef HAVE_RPCSVC_DBM_H +/* Define to use libmd SHA1 functions instead of OpenSSL libcrypto */ +#undef HAVE_SHA1_IN_LIBMD + /* Define to 1 if you have the `shmctl64' function. */ #undef HAVE_SHMCTL64 diff --git a/render/Makefile.am b/render/Makefile.am index 5bb844622..e53c7c746 100644 --- a/render/Makefile.am +++ b/render/Makefile.am @@ -13,11 +13,8 @@ librender_la_SOURCES = \ mitri.c \ picture.c \ render.c \ - sha1.c \ renderedge.c if XORG sdk_HEADERS = picture.h mipict.h glyphstr.h picturestr.h renderedge.h endif - -EXTRA_DIST = sha1.h diff --git a/render/glyph.c b/render/glyph.c index 949e02340..849e65fce 100644 --- a/render/glyph.c +++ b/render/glyph.c @@ -26,7 +26,13 @@ #include <dix-config.h> #endif -#include "sha1.h" +#ifdef HAVE_SHA1_IN_LIBMD /* Use libmd for SHA1 */ +# include <sha1.h> +#else /* Use OpenSSL's libcrypto */ +# include <stddef.h> /* buggy openssl/sha.h wants size_t */ +# include <openssl/sha.h> +#endif + #include "misc.h" #include "scrnintstr.h" #include "os.h" @@ -192,12 +198,33 @@ HashGlyph (xGlyphInfo *gi, unsigned long size, unsigned char sha1[20]) { +#ifdef HAVE_SHA1_IN_LIBMD /* Use libmd for SHA1 */ SHA1_CTX ctx; SHA1Init (&ctx); SHA1Update (&ctx, gi, sizeof (xGlyphInfo)); SHA1Update (&ctx, bits, size); SHA1Final (sha1, &ctx); +#else /* Use OpenSSL's libcrypto */ + SHA_CTX ctx; + int success; + + success = SHA1_Init (&ctx); + if (! success) + return BadAlloc; + + success = SHA1_Update (&ctx, gi, sizeof (xGlyphInfo)); + if (! success) + return BadAlloc; + + success = SHA1_Update (&ctx, bits, size); + if (! success) + return BadAlloc; + + success = SHA1_Final (sha1, &ctx); + if (! success) + return BadAlloc; +#endif return Success; } diff --git a/render/sha1.c b/render/sha1.c deleted file mode 100644 index 820eb2a33..000000000 --- a/render/sha1.c +++ /dev/null @@ -1,173 +0,0 @@ -/* - * SHA-1 in C - * By Steve Reid <steve@edmweb.com> - * 100% Public Domain - * - * Test Vectors (from FIPS PUB 180-1) - * "abc" - * A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D - * "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" - * 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 - * A million repetitions of "a" - * 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F - */ - -#include <sys/param.h> -#include <string.h> -#include <sha1.h> - -#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) - -/* - * blk0() and blk() perform the initial expand. - * I got the idea of expanding during the round function from SSLeay - */ -#if BYTE_ORDER == LITTLE_ENDIAN -# define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \ - |(rol(block->l[i],8)&0x00FF00FF)) -#else -# define blk0(i) block->l[i] -#endif -#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \ - ^block->l[(i+2)&15]^block->l[i&15],1)) - -/* - * (R0+R1), R2, R3, R4 are the different operations (rounds) used in SHA1 - */ -#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30); -#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30); -#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30); -#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30); -#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30); - -/* - * Hash a single 512-bit block. This is the core of the algorithm. - */ -void -SHA1Transform(uint32_t state[5], const uint8_t buffer[SHA1_BLOCK_LENGTH]) -{ - uint32_t a, b, c, d, e; - uint8_t workspace[SHA1_BLOCK_LENGTH]; - typedef union { - uint8_t c[64]; - uint32_t l[16]; - } CHAR64LONG16; - CHAR64LONG16 *block = (CHAR64LONG16 *)workspace; - - (void)memcpy(block, buffer, SHA1_BLOCK_LENGTH); - - /* Copy context->state[] to working vars */ - a = state[0]; - b = state[1]; - c = state[2]; - d = state[3]; - e = state[4]; - - /* 4 rounds of 20 operations each. Loop unrolled. */ - R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3); - R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7); - R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11); - R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15); - R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); - R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); - R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); - R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); - R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); - R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); - R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); - R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); - R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); - R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); - R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); - R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); - R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); - R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); - R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); - R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); - - /* Add the working vars back into context.state[] */ - state[0] += a; - state[1] += b; - state[2] += c; - state[3] += d; - state[4] += e; - - /* Wipe variables */ - a = b = c = d = e = 0; -} - - -/* - * SHA1Init - Initialize new context - */ -void -SHA1Init(SHA1_CTX *context) -{ - - /* SHA1 initialization constants */ - context->count = 0; - context->state[0] = 0x67452301; - context->state[1] = 0xEFCDAB89; - context->state[2] = 0x98BADCFE; - context->state[3] = 0x10325476; - context->state[4] = 0xC3D2E1F0; -} - - -/* - * Run your data through this. - */ -void -SHA1Update(SHA1_CTX *context, const uint8_t *data, size_t len) -{ - size_t i, j; - - j = (size_t)((context->count >> 3) & 63); - context->count += (len << 3); - if ((j + len) > 63) { - (void)memcpy(&context->buffer[j], data, (i = 64-j)); - SHA1Transform(context->state, context->buffer); - for ( ; i + 63 < len; i += 64) - SHA1Transform(context->state, (uint8_t *)&data[i]); - j = 0; - } else { - i = 0; - } - (void)memcpy(&context->buffer[j], &data[i], len - i); -} - - -/* - * Add padding and return the message digest. - */ -void -SHA1Pad(SHA1_CTX *context) -{ - uint8_t finalcount[8]; - uint i; - - for (i = 0; i < 8; i++) { - finalcount[i] = (uint8_t)((context->count >> - ((7 - (i & 7)) * 8)) & 255); /* Endian independent */ - } - SHA1Update(context, (uint8_t *)"\200", 1); - while ((context->count & 504) != 448) - SHA1Update(context, (uint8_t *)"\0", 1); - SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */ -} - -void -SHA1Final(uint8_t digest[SHA1_DIGEST_LENGTH], SHA1_CTX *context) -{ - uint i; - - SHA1Pad(context); - if (digest) { - for (i = 0; i < SHA1_DIGEST_LENGTH; i++) { - digest[i] = (uint8_t) - ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); - } - memset(context, 0, sizeof(*context)); - } -} - diff --git a/render/sha1.h b/render/sha1.h deleted file mode 100644 index ace7d97c0..000000000 --- a/render/sha1.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * SHA-1 in C - * By Steve Reid <steve@edmweb.com> - * 100% Public Domain - */ - -#ifndef _SHA1_H -#define _SHA1_H - -#include <stdint.h> -#include <stddef.h> -#include <unistd.h> - - -#define SHA1_BLOCK_LENGTH 64 -#define SHA1_DIGEST_LENGTH 20 -#define SHA1_DIGEST_STRING_LENGTH (SHA1_DIGEST_LENGTH * 2 + 1) - -typedef struct { - uint32_t state[5]; - uint64_t count; - uint8_t buffer[SHA1_BLOCK_LENGTH]; -} SHA1_CTX; - -#include <sys/cdefs.h> - -__BEGIN_DECLS -void SHA1Init(SHA1_CTX *); -void SHA1Pad(SHA1_CTX *); -void SHA1Transform(uint32_t [5], const uint8_t [SHA1_BLOCK_LENGTH]) - __attribute__((__bounded__(__minbytes__,1,5))) - __attribute__((__bounded__(__minbytes__,2,SHA1_BLOCK_LENGTH))); -void SHA1Update(SHA1_CTX *, const uint8_t *, size_t) - __attribute__((__bounded__(__string__,2,3))); -void SHA1Final(uint8_t [SHA1_DIGEST_LENGTH], SHA1_CTX *) - __attribute__((__bounded__(__minbytes__,1,SHA1_DIGEST_LENGTH))); -char *SHA1End(SHA1_CTX *, char *) - __attribute__((__bounded__(__minbytes__,2,SHA1_DIGEST_STRING_LENGTH))); -char *SHA1File(const char *, char *) - __attribute__((__bounded__(__minbytes__,2,SHA1_DIGEST_STRING_LENGTH))); -char *SHA1FileChunk(const char *, char *, off_t, off_t) - __attribute__((__bounded__(__minbytes__,2,SHA1_DIGEST_STRING_LENGTH))); -char *SHA1Data(const uint8_t *, size_t, char *) - __attribute__((__bounded__(__string__,1,2))) - __attribute__((__bounded__(__minbytes__,3,SHA1_DIGEST_STRING_LENGTH))); -__END_DECLS - -#define HTONDIGEST(x) do { \ - x[0] = htonl(x[0]); \ - x[1] = htonl(x[1]); \ - x[2] = htonl(x[2]); \ - x[3] = htonl(x[3]); \ - x[4] = htonl(x[4]); } while (0) - -#define NTOHDIGEST(x) do { \ - x[0] = ntohl(x[0]); \ - x[1] = ntohl(x[1]); \ - x[2] = ntohl(x[2]); \ - x[3] = ntohl(x[3]); \ - x[4] = ntohl(x[4]); } while (0) - -#endif /* _SHA1_H */ - |