Here is an implementation I've written myself, so no license issues. OG.
On Fri, Dec 12, 2014 at 10:48 AM, Jose Fonseca <jfons...@vmware.com> wrote: > On 11/12/14 22:02, Brian Paul wrote: >> >> On 12/11/2014 02:51 PM, Carl Worth wrote: >>> >>> From: Kristian Høgsberg <k...@bitplanet.net> >>> >>> The upcoming shader cache uses the SHA-1 algorithm for cryptographic >>> naming. These new mesa_sha1 functions are implemented with the nettle >>> library. >>> --- >>> >>> This patch is another in support of my upcoming shader-cache work. >>> Thanks to >>> Kritian for coding this piece. >>> >>> As currently written, this patch introduces a new dependency of Mesa >>> on the >>> Nettle library to implement SHA-1. I'm open to recommendations if >>> people would prefer some other option. >>> >>> For example, the xserver can be configured to get a SHA-1 >>> implementation from >>> libmd, libc, CommonCrypto, CryptoAPI, libnettle, libgcrypt, libsha1, or >>> openssl. >>> >>> I don't know if it's important to offer as many options as that, which >>> is why >>> I'm asking for opinions here. >> >> >> >> We'll need a solution for Windows too. I don't have time right now to >> do any research into that. > > > Yes, ideally we'd have something small that we could bundle into mesa source > tree, for sake of non Linux OSes. > > If Windows was the only concern, we could use its Crypto API, > http://msdn.microsoft.com/en-us/library/windows/desktop/aa382379.aspx and > avoid depending on anything else, but some of the above mention libraries > are not trivial to install. > > The other alternative is to disable shader cache when no suitable dependency > is found. That is, make this an optional dependency. > > Jose > > _______________________________________________ > mesa-dev mailing list > mesa-dev@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/mesa-dev
/* * Copyright © 2014 Olivier Galibert & Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include <stdlib.h> #include <string.h> #include "sha1.h" static inline unsigned int mesa_sha1_shift(unsigned int val, int count) { return (val << count) | (val >> (32-count)); } static void mesa_sha1_init(struct mesa_sha1 *ctx) { ctx->digest[0] = 0x67452301; ctx->digest[1] = 0xefcdab89; ctx->digest[2] = 0x98badcfe; ctx->digest[3] = 0x10325476; ctx->digest[4] = 0xc3d2e1f0; ctx->msize = 0; } static void mesa_sha1_handle_block(struct mesa_sha1 *ctx, const unsigned char *b) { unsigned int W[80]; for(int i=0; i != 16; i++) W[i] = (b[4*i] << 24) | (b[4*i+1] << 16) | (b[4*i+2] << 8) | b[4*i+3]; for(int i=16; i != 80; i++) W[i] = mesa_sha1_shift(W[i-3]^W[i-8]^W[i-14]^W[i-16], 1); unsigned int A = ctx->digest[0]; unsigned int B = ctx->digest[1]; unsigned int C = ctx->digest[2]; unsigned int D = ctx->digest[3]; unsigned int E = ctx->digest[4]; for(int i= 0; i != 20; i++) { unsigned int T = mesa_sha1_shift(A, 5) + ((B & C) | ((~B) & D)) + E + W[i] + 0x5A827999; E = D; D = C; C = mesa_sha1_shift(B, 30); B = A; A = T; } for(int i=20; i != 40; i++) { unsigned int T = mesa_sha1_shift(A, 5) + (B^C^D) + E + W[i] + 0x6ed9eba1; E = D; D = C; C = mesa_sha1_shift(B, 30); B = A; A = T; } for(int i=40; i != 60; i++) { unsigned int T = mesa_sha1_shift(A, 5) + ((B & C) | (B & D) | (C & D)) + E + W[i] + 0x8f1bbcdc; E = D; D = C; C = mesa_sha1_shift(B, 30); B = A; A = T; } for(int i=60; i != 80; i++) { unsigned int T = mesa_sha1_shift(A, 5) + (B^C^D) + E + W[i] + 0xca62c1d6; E = D; D = C; C = mesa_sha1_shift(B, 30); B = A; A = T; } ctx->digest[0] += A; ctx->digest[1] += B; ctx->digest[2] += C; ctx->digest[3] += D; ctx->digest[4] += E; } void mesa_sha1_final(struct mesa_sha1 *ctx, unsigned char result[20]) { unsigned int offset = ctx->msize & 63; ctx->block[offset] = 0x80; memset(ctx->block+offset+1, 0, 64-offset-1); if(offset > 55) { mesa_sha1_handle_block(ctx, ctx->block); memset(ctx->block, 0, 64); } ctx->block[59] = ctx->msize >> 29; ctx->block[60] = ctx->msize >> 21; ctx->block[61] = ctx->msize >> 13; ctx->block[62] = ctx->msize >> 5; ctx->block[63] = ctx->msize << 3; mesa_sha1_handle_block(ctx, ctx->block); for(int i=0; i<20; i++) result[i] = ctx->digest[i >> 2] >> (28 - 8*(i & 3)); } struct mesa_sha1 * _mesa_sha1_init(void) { struct mesa_sha1 *ctx = (struct mesa_sha1 *)malloc(sizeof(*ctx)); if (!ctx) return NULL; mesa_sha1_init(ctx); return ctx; } int _mesa_sha1_update(struct mesa_sha1 *ctx, const void *data, int size) { const unsigned char *pdata = (const unsigned char *)data; unsigned int offset = ctx->msize & 63; ctx->msize += size; if(offset) { if(offset+size >= 64) { memcpy(ctx->block+offset, pdata, 64-offset); mesa_sha1_handle_block(ctx, ctx->block); pdata += offset; size -= offset; } } while(size >= 64) { mesa_sha1_handle_block(ctx, pdata); pdata += 64; size -= 64; } if(size) memcpy(ctx->block, pdata, size); return 1; } int _mesa_sha1_final(struct mesa_sha1 *ctx, unsigned char result[20]) { mesa_sha1_final(ctx, result); free(ctx); return 1; } void _mesa_sha1_compute(const void *data, size_t size, unsigned char result[20]) { struct mesa_sha1 ctx; mesa_sha1_init(&ctx); _mesa_sha1_update(&ctx, data, size); mesa_sha1_final(&ctx, result); } char * _mesa_sha1_format(char *buf, const unsigned char *sha1) { static const char hex_digits[] = "0123456789abcdef"; int i; for (i = 0; i < 40; i += 2) { buf[i] = hex_digits[sha1[i >> 1] >> 4]; buf[i + 1] = hex_digits[sha1[i >> 1] & 0x0f]; } buf[i] = '\0'; return buf; }
#ifndef SHA1_H #define SHA1_H #ifdef __cplusplus extern "C" { #endif #include <stdlib.h> struct mesa_sha1 { unsigned char block[64]; unsigned int digest[5]; unsigned int msize; }; struct mesa_sha1 *_mesa_sha1_init(void); int _mesa_sha1_update(struct mesa_sha1 *ctx, const void *data, int size); int _mesa_sha1_final(struct mesa_sha1 *ctx, unsigned char result[20]); char *_mesa_sha1_format(char *buf, const unsigned char *sha1); void _mesa_sha1_compute(const void *data, size_t size, unsigned char result[20]); #ifdef __cplusplus } /* extern C */ #endif #endif
_______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev