├── openbsd-58-base.pub ├── patched-src ├── explicit_bzero.c ├── crypto_api.c ├── timingsafe_bcmp.c ├── crypto_api.h ├── ge25519.h ├── strlcpy.c ├── err.c ├── errx.c ├── verrx.c ├── verr.c ├── fe25519.h ├── sc25519.h ├── mod_ed25519.c ├── sha2.h ├── smult_curve25519_ref.c ├── sc25519.c ├── fe25519.c ├── base64.c ├── mod_ge25519.c ├── signify.c └── sha2.c ├── mingw.h ├── Makefile ├── prepare.sh ├── README.md └── mingw.diff /openbsd-58-base.pub: -------------------------------------------------------------------------------- 1 | untrusted comment: openbsd 5.8 base public key 2 | RWQNNZXtC/MqP3Eiu+6FBz/qrxiWQwDhd+9Yljzp62UP4KzFmmvzVk60 3 | -------------------------------------------------------------------------------- /patched-src/explicit_bzero.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD: explicit_bzero.c,v 1.3 2014/06/21 02:34:26 matthew Exp $ */ 2 | /* 3 | * Public domain. 4 | * Written by Matthew Dempsky. 5 | */ 6 | 7 | #include 8 | 9 | __attribute__((weak)) void 10 | __explicit_bzero_hook(void *buf, size_t len) 11 | { 12 | } 13 | 14 | void 15 | explicit_bzero(void *buf, size_t len) 16 | { 17 | memset(buf, 0, len); 18 | __explicit_bzero_hook(buf, len); 19 | } 20 | -------------------------------------------------------------------------------- /mingw.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | /* define some types not known to MinGW */ 4 | typedef unsigned char u_char; 5 | typedef unsigned char u_int8_t; 6 | typedef unsigned int u_int32_t; 7 | typedef unsigned long long u_int64_t; 8 | 9 | /* function prototypes stolen from OpenBSD include files */ 10 | size_t strlcpy(char *, const char *, size_t) __attribute__ ((__bounded__(__string__,1,3))); 11 | int b64_pton(char const *, unsigned char *, size_t); 12 | void explicit_bzero(void *, size_t) __attribute__ ((__bounded__(__buffer__,1,2))); 13 | int timingsafe_bcmp(const void *, const void *, size_t); 14 | void err(int, const char *, ...); 15 | void errx(int, const char *, ...); 16 | -------------------------------------------------------------------------------- /patched-src/crypto_api.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD: crypto_api.c,v 1.1 2014/01/08 03:59:46 tedu Exp $ */ 2 | /* 3 | * Public domain. Author: Ted Unangst 4 | * API compatible reimplementation of functions from nacl 5 | */ 6 | #include "mingw.h" 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | #include "crypto_api.h" 14 | 15 | int 16 | crypto_hash_sha512(unsigned char *out, const unsigned char *in, 17 | unsigned long long inlen) 18 | { 19 | SHA2_CTX ctx; 20 | 21 | SHA512Init(&ctx); 22 | SHA512Update(&ctx, in, inlen); 23 | SHA512Final(out, &ctx); 24 | return 0; 25 | } 26 | 27 | int 28 | crypto_verify_32(const unsigned char *x, const unsigned char *y) 29 | { 30 | return timingsafe_bcmp(x, y, 32) ? -1 : 0; 31 | } 32 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | SOURCES := $(wildcard *.c) 2 | OBJECTS := $(SOURCES:.c=.o) 3 | # had no rm installed 4 | RM := del 5 | 6 | # signify will only support verification 7 | CFLAGS += -DVERIFYONLY 8 | # look in current directory for sha2.h include 9 | CFLAGS += -I. 10 | # OpenBSD default for amd64/i386 11 | CFLAGS += -O2 -pipe 12 | # amd64/i386 are little endian machines 13 | CFLAGS += -DBYTE_ORDER=LITTLE_ENDIAN 14 | # O_NOFOLLOW not defined, but we can live without it 15 | CFLAGS += -DO_NOFOLLOW=0 16 | # only sha256 is required 17 | CFLAGS += -DSHA2_SMALL 18 | # suppress warnings you would see with MinGW 19 | CFLAGS += -Wno-pointer-sign -Wno-attributes 20 | 21 | all: signify.exe 22 | 23 | signify.exe: $(OBJECTS) 24 | ${CC} -o $@ $^ 25 | 26 | %.o: %.c 27 | ${CC} ${CFLAGS} -o $@ -c $^ 28 | 29 | clean: 30 | ${RM} signify.exe ${OBJECTS} 31 | -------------------------------------------------------------------------------- /prepare.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # If you don't have an OpenBSD 5.8 source tree installed, 4 | # extract files from the src.tar.gz archive. 5 | SRC=/usr/src 6 | 7 | for file in \ 8 | include/sha2.h \ 9 | lib/libc/gen/err.c \ 10 | lib/libc/gen/errx.c \ 11 | lib/libc/gen/verr.c \ 12 | lib/libc/gen/verrx.c \ 13 | lib/libc/hash/sha2.c \ 14 | lib/libc/net/base64.c \ 15 | lib/libc/string/explicit_bzero.c \ 16 | lib/libc/string/strlcpy.c \ 17 | lib/libc/string/timingsafe_bcmp.c \ 18 | usr.bin/signify/crypto_api.c \ 19 | usr.bin/signify/crypto_api.h \ 20 | usr.bin/signify/fe25519.c \ 21 | usr.bin/signify/fe25519.h \ 22 | usr.bin/signify/ge25519.h \ 23 | usr.bin/signify/ge25519_base.data \ 24 | usr.bin/signify/mod_ed25519.c \ 25 | usr.bin/signify/mod_ge25519.c \ 26 | usr.bin/signify/sc25519.c \ 27 | usr.bin/signify/sc25519.h \ 28 | usr.bin/signify/signify.c \ 29 | usr.bin/signify/smult_curve25519_ref.c 30 | do 31 | cp $SRC/$file . 32 | done 33 | 34 | -------------------------------------------------------------------------------- /patched-src/timingsafe_bcmp.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD: timingsafe_bcmp.c,v 1.2 2014/06/10 04:17:37 deraadt Exp $ */ 2 | /* 3 | * Copyright (c) 2010 Damien Miller. All rights reserved. 4 | * 5 | * Permission to use, copy, modify, and distribute this software for any 6 | * purpose with or without fee is hereby granted, provided that the above 7 | * copyright notice and this permission notice appear in all copies. 8 | * 9 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 | */ 17 | 18 | #include 19 | 20 | int 21 | timingsafe_bcmp(const void *b1, const void *b2, size_t n) 22 | { 23 | const unsigned char *p1 = b1, *p2 = b2; 24 | int ret = 0; 25 | 26 | for (; n > 0; n--) 27 | ret |= *p1++ ^ *p2++; 28 | return (ret != 0); 29 | } 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # signify -V for Windows systems 2 | 3 | The signify utility, developed by the OpenBSD project, 4 | is used to create and verify cryptographic signatures. 5 | OpenBSD uses it for their installation files. 6 | 7 | If you want to install OpenBSD for the first time, you won't 8 | have an OpenBSD installation around to execute this tool to 9 | verify the integrity of your file sets. 10 | 11 | Portable versions already exist for Linux and other 12 | Unix-like systems. If you use Windows as your main system, 13 | you can use this project instead. 14 | 15 | # How to compile 16 | 17 | ## Host requirements 18 | 19 | I used MinGW to compile signify on Windows. 20 | 21 | ## Set up source files 22 | 23 | Either copy all files from patched-src into top directory. 24 | 25 | Or you can copy all required files from OpenBSD's source tree. 26 | For this, I have used latest OpenBSD 5.8 src.tar.gz. In that case, 27 | look at prepare.sh and copy files manually. If you do this, finally 28 | apply the patch mingw.diff. This eventually leads to the same 29 | files as you can find in patched-src. 30 | 31 | Having the file mingw.diff around is a great way to look at the 32 | required changes to get signify run on Windows -- it's not much! 33 | 34 | # Execution 35 | 36 | Run signify always with -V (verify) argument. If you want to create 37 | signatures, use signify from within OpenBSD after your installation. ;) 38 | -------------------------------------------------------------------------------- /patched-src/crypto_api.h: -------------------------------------------------------------------------------- 1 | /* $OpenBSD: crypto_api.h,v 1.1 2014/07/22 00:41:19 deraadt Exp $ */ 2 | 3 | /* 4 | * Assembled from generated headers and source files by Markus Friedl. 5 | * Placed in the public domain. 6 | */ 7 | 8 | #ifndef crypto_api_h 9 | #define crypto_api_h 10 | 11 | #include 12 | #include 13 | 14 | typedef int32_t crypto_int32; 15 | typedef uint32_t crypto_uint32; 16 | 17 | #define randombytes(buf, buf_len) arc4random_buf((buf), (buf_len)) 18 | 19 | #define crypto_hashblocks_sha512_STATEBYTES 64U 20 | #define crypto_hashblocks_sha512_BLOCKBYTES 128U 21 | 22 | int crypto_hashblocks_sha512(unsigned char *, const unsigned char *, 23 | unsigned long long); 24 | 25 | #define crypto_hash_sha512_BYTES 64U 26 | 27 | int crypto_hash_sha512(unsigned char *, const unsigned char *, 28 | unsigned long long); 29 | 30 | int crypto_verify_32(const unsigned char *, const unsigned char *); 31 | 32 | #define crypto_sign_ed25519_SECRETKEYBYTES 64U 33 | #define crypto_sign_ed25519_PUBLICKEYBYTES 32U 34 | #define crypto_sign_ed25519_BYTES 64U 35 | 36 | int crypto_sign_ed25519(unsigned char *, unsigned long long *, 37 | const unsigned char *, unsigned long long, const unsigned char *); 38 | int crypto_sign_ed25519_open(unsigned char *, unsigned long long *, 39 | const unsigned char *, unsigned long long, const unsigned char *); 40 | int crypto_sign_ed25519_keypair(unsigned char *, unsigned char *); 41 | 42 | #endif /* crypto_api_h */ 43 | -------------------------------------------------------------------------------- /patched-src/ge25519.h: -------------------------------------------------------------------------------- 1 | /* $OpenBSD: ge25519.h,v 1.2 2015/02/16 18:26:26 miod Exp $ */ 2 | 3 | /* 4 | * Public Domain, Authors: Daniel J. Bernstein, Niels Duif, Tanja Lange, 5 | * Peter Schwabe, Bo-Yin Yang. 6 | * Copied from supercop-20130419/crypto_sign/ed25519/ref/ge25519.h 7 | */ 8 | 9 | #ifndef GE25519_H 10 | #define GE25519_H 11 | 12 | #include "fe25519.h" 13 | #include "sc25519.h" 14 | 15 | #define ge25519 crypto_sign_ed25519_ref_ge25519 16 | #define ge25519_base crypto_sign_ed25519_ref_ge25519_base 17 | #define ge25519_unpackneg_vartime crypto_sign_ed25519_ref_unpackneg_vartime 18 | #define ge25519_pack crypto_sign_ed25519_ref_pack 19 | #define ge25519_isneutral_vartime crypto_sign_ed25519_ref_isneutral_vartime 20 | #define ge25519_double_scalarmult_vartime crypto_sign_ed25519_ref_double_scalarmult_vartime 21 | #define ge25519_scalarmult_base crypto_sign_ed25519_ref_scalarmult_base 22 | 23 | typedef struct 24 | { 25 | fe25519 x; 26 | fe25519 y; 27 | fe25519 z; 28 | fe25519 t; 29 | } ge25519; 30 | 31 | extern const ge25519 ge25519_base; 32 | 33 | int ge25519_unpackneg_vartime(ge25519 *r, const unsigned char p[32]); 34 | 35 | void ge25519_pack(unsigned char r[32], const ge25519 *p); 36 | 37 | int ge25519_isneutral_vartime(const ge25519 *p); 38 | 39 | void ge25519_double_scalarmult_vartime(ge25519 *r, const ge25519 *p1, const sc25519 *s1, const ge25519 *p2, const sc25519 *s2); 40 | 41 | void ge25519_scalarmult_base(ge25519 *r, const sc25519 *s); 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /patched-src/strlcpy.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD: strlcpy.c,v 1.12 2015/01/15 03:54:12 millert Exp $ */ 2 | 3 | /* 4 | * Copyright (c) 1998, 2015 Todd C. Miller 5 | * 6 | * Permission to use, copy, modify, and distribute this software for any 7 | * purpose with or without fee is hereby granted, provided that the above 8 | * copyright notice and this permission notice appear in all copies. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 | */ 18 | 19 | #include 20 | #include 21 | 22 | /* 23 | * Copy string src to buffer dst of size dsize. At most dsize-1 24 | * chars will be copied. Always NUL terminates (unless dsize == 0). 25 | * Returns strlen(src); if retval >= dsize, truncation occurred. 26 | */ 27 | size_t 28 | strlcpy(char *dst, const char *src, size_t dsize) 29 | { 30 | const char *osrc = src; 31 | size_t nleft = dsize; 32 | 33 | /* Copy as many bytes as will fit. */ 34 | if (nleft != 0) { 35 | while (--nleft != 0) { 36 | if ((*dst++ = *src++) == '\0') 37 | break; 38 | } 39 | } 40 | 41 | /* Not enough room in dst, add NUL and traverse rest of src. */ 42 | if (nleft == 0) { 43 | if (dsize != 0) 44 | *dst = '\0'; /* NUL-terminate dst */ 45 | while (*src++) 46 | ; 47 | } 48 | 49 | return(src - osrc - 1); /* count does not include NUL */ 50 | } 51 | -------------------------------------------------------------------------------- /patched-src/err.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD: err.c,v 1.11 2012/12/05 23:19:59 deraadt Exp $ */ 2 | /*- 3 | * Copyright (c) 1993 4 | * The Regents of the University of California. All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 1. Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 3. Neither the name of the University nor the names of its contributors 15 | * may be used to endorse or promote products derived from this software 16 | * without specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 19 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 22 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 | * SUCH DAMAGE. 29 | */ 30 | 31 | #include 32 | 33 | /* PRINTFLIKE2 */ 34 | void 35 | err(int eval, const char *fmt, ...) 36 | { 37 | va_list ap; 38 | 39 | va_start(ap, fmt); 40 | _verr(eval, fmt, ap); 41 | va_end(ap); 42 | } 43 | 44 | -------------------------------------------------------------------------------- /patched-src/errx.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD: errx.c,v 1.10 2012/12/05 23:19:59 deraadt Exp $ */ 2 | /*- 3 | * Copyright (c) 1993 4 | * The Regents of the University of California. All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 1. Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 3. Neither the name of the University nor the names of its contributors 15 | * may be used to endorse or promote products derived from this software 16 | * without specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 19 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 22 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 | * SUCH DAMAGE. 29 | */ 30 | 31 | #include 32 | 33 | /* PRINTFLIKE2 */ 34 | void 35 | errx(int eval, const char *fmt, ...) 36 | { 37 | va_list ap; 38 | 39 | va_start(ap, fmt); 40 | _verrx(eval, fmt, ap); 41 | va_end(ap); 42 | } 43 | 44 | -------------------------------------------------------------------------------- /patched-src/verrx.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD: verrx.c,v 1.9 2012/12/05 23:20:00 deraadt Exp $ */ 2 | /*- 3 | * Copyright (c) 1993 4 | * The Regents of the University of California. All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 1. Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 3. Neither the name of the University nor the names of its contributors 15 | * may be used to endorse or promote products derived from this software 16 | * without specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 19 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 22 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 | * SUCH DAMAGE. 29 | */ 30 | 31 | #include 32 | #include 33 | #include 34 | 35 | extern char *__progname; /* Program name, from crt0. */ 36 | 37 | void 38 | _verrx(int eval, const char *fmt, va_list ap) 39 | { 40 | (void)fprintf(stderr, "%s: ", __progname); 41 | if (fmt != NULL) 42 | (void)vfprintf(stderr, fmt, ap); 43 | (void)fprintf(stderr, "\n"); 44 | exit(eval); 45 | } 46 | 47 | -------------------------------------------------------------------------------- /patched-src/verr.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD: verr.c,v 1.9 2012/12/05 23:20:00 deraadt Exp $ */ 2 | /*- 3 | * Copyright (c) 1993 4 | * The Regents of the University of California. All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 1. Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 3. Neither the name of the University nor the names of its contributors 15 | * may be used to endorse or promote products derived from this software 16 | * without specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 19 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 22 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 | * SUCH DAMAGE. 29 | */ 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | 37 | extern char *__progname; /* Program name, from crt0. */ 38 | 39 | void 40 | _verr(int eval, const char *fmt, va_list ap) 41 | { 42 | int sverrno; 43 | 44 | sverrno = errno; 45 | (void)fprintf(stderr, "%s: ", __progname); 46 | if (fmt != NULL) { 47 | (void)vfprintf(stderr, fmt, ap); 48 | (void)fprintf(stderr, ": "); 49 | } 50 | (void)fprintf(stderr, "%s\n", strerror(sverrno)); 51 | exit(eval); 52 | } 53 | 54 | -------------------------------------------------------------------------------- /patched-src/fe25519.h: -------------------------------------------------------------------------------- 1 | /* $OpenBSD: fe25519.h,v 1.1 2014/07/22 00:41:19 deraadt Exp $ */ 2 | 3 | /* 4 | * Public Domain, Authors: Daniel J. Bernstein, Niels Duif, Tanja Lange, 5 | * Peter Schwabe, Bo-Yin Yang. 6 | * Copied from supercop-20130419/crypto_sign/ed25519/ref/fe25519.h 7 | */ 8 | 9 | #ifndef FE25519_H 10 | #define FE25519_H 11 | 12 | #include "crypto_api.h" 13 | 14 | #define fe25519 crypto_sign_ed25519_ref_fe25519 15 | #define fe25519_freeze crypto_sign_ed25519_ref_fe25519_freeze 16 | #define fe25519_unpack crypto_sign_ed25519_ref_fe25519_unpack 17 | #define fe25519_pack crypto_sign_ed25519_ref_fe25519_pack 18 | #define fe25519_iszero crypto_sign_ed25519_ref_fe25519_iszero 19 | #define fe25519_iseq_vartime crypto_sign_ed25519_ref_fe25519_iseq_vartime 20 | #define fe25519_cmov crypto_sign_ed25519_ref_fe25519_cmov 21 | #define fe25519_setone crypto_sign_ed25519_ref_fe25519_setone 22 | #define fe25519_setzero crypto_sign_ed25519_ref_fe25519_setzero 23 | #define fe25519_neg crypto_sign_ed25519_ref_fe25519_neg 24 | #define fe25519_getparity crypto_sign_ed25519_ref_fe25519_getparity 25 | #define fe25519_add crypto_sign_ed25519_ref_fe25519_add 26 | #define fe25519_sub crypto_sign_ed25519_ref_fe25519_sub 27 | #define fe25519_mul crypto_sign_ed25519_ref_fe25519_mul 28 | #define fe25519_square crypto_sign_ed25519_ref_fe25519_square 29 | #define fe25519_invert crypto_sign_ed25519_ref_fe25519_invert 30 | #define fe25519_pow2523 crypto_sign_ed25519_ref_fe25519_pow2523 31 | 32 | typedef struct 33 | { 34 | crypto_uint32 v[32]; 35 | } 36 | fe25519; 37 | 38 | void fe25519_freeze(fe25519 *r); 39 | 40 | void fe25519_unpack(fe25519 *r, const unsigned char x[32]); 41 | 42 | void fe25519_pack(unsigned char r[32], const fe25519 *x); 43 | 44 | int fe25519_iszero(const fe25519 *x); 45 | 46 | int fe25519_iseq_vartime(const fe25519 *x, const fe25519 *y); 47 | 48 | void fe25519_cmov(fe25519 *r, const fe25519 *x, unsigned char b); 49 | 50 | void fe25519_setone(fe25519 *r); 51 | 52 | void fe25519_setzero(fe25519 *r); 53 | 54 | void fe25519_neg(fe25519 *r, const fe25519 *x); 55 | 56 | unsigned char fe25519_getparity(const fe25519 *x); 57 | 58 | void fe25519_add(fe25519 *r, const fe25519 *x, const fe25519 *y); 59 | 60 | void fe25519_sub(fe25519 *r, const fe25519 *x, const fe25519 *y); 61 | 62 | void fe25519_mul(fe25519 *r, const fe25519 *x, const fe25519 *y); 63 | 64 | void fe25519_square(fe25519 *r, const fe25519 *x); 65 | 66 | void fe25519_invert(fe25519 *r, const fe25519 *x); 67 | 68 | void fe25519_pow2523(fe25519 *r, const fe25519 *x); 69 | 70 | #endif 71 | -------------------------------------------------------------------------------- /patched-src/sc25519.h: -------------------------------------------------------------------------------- 1 | /* $OpenBSD: sc25519.h,v 1.1 2014/07/22 00:41:19 deraadt Exp $ */ 2 | 3 | /* 4 | * Public Domain, Authors: Daniel J. Bernstein, Niels Duif, Tanja Lange, 5 | * Peter Schwabe, Bo-Yin Yang. 6 | * Copied from supercop-20130419/crypto_sign/ed25519/ref/sc25519.h 7 | */ 8 | 9 | #ifndef SC25519_H 10 | #define SC25519_H 11 | 12 | #include "crypto_api.h" 13 | 14 | #define sc25519 crypto_sign_ed25519_ref_sc25519 15 | #define shortsc25519 crypto_sign_ed25519_ref_shortsc25519 16 | #define sc25519_from32bytes crypto_sign_ed25519_ref_sc25519_from32bytes 17 | #define shortsc25519_from16bytes crypto_sign_ed25519_ref_shortsc25519_from16bytes 18 | #define sc25519_from64bytes crypto_sign_ed25519_ref_sc25519_from64bytes 19 | #define sc25519_from_shortsc crypto_sign_ed25519_ref_sc25519_from_shortsc 20 | #define sc25519_to32bytes crypto_sign_ed25519_ref_sc25519_to32bytes 21 | #define sc25519_iszero_vartime crypto_sign_ed25519_ref_sc25519_iszero_vartime 22 | #define sc25519_isshort_vartime crypto_sign_ed25519_ref_sc25519_isshort_vartime 23 | #define sc25519_lt_vartime crypto_sign_ed25519_ref_sc25519_lt_vartime 24 | #define sc25519_add crypto_sign_ed25519_ref_sc25519_add 25 | #define sc25519_sub_nored crypto_sign_ed25519_ref_sc25519_sub_nored 26 | #define sc25519_mul crypto_sign_ed25519_ref_sc25519_mul 27 | #define sc25519_mul_shortsc crypto_sign_ed25519_ref_sc25519_mul_shortsc 28 | #define sc25519_window3 crypto_sign_ed25519_ref_sc25519_window3 29 | #define sc25519_window5 crypto_sign_ed25519_ref_sc25519_window5 30 | #define sc25519_2interleave2 crypto_sign_ed25519_ref_sc25519_2interleave2 31 | 32 | typedef struct 33 | { 34 | crypto_uint32 v[32]; 35 | } 36 | sc25519; 37 | 38 | typedef struct 39 | { 40 | crypto_uint32 v[16]; 41 | } 42 | shortsc25519; 43 | 44 | void sc25519_from32bytes(sc25519 *r, const unsigned char x[32]); 45 | 46 | void shortsc25519_from16bytes(shortsc25519 *r, const unsigned char x[16]); 47 | 48 | void sc25519_from64bytes(sc25519 *r, const unsigned char x[64]); 49 | 50 | void sc25519_from_shortsc(sc25519 *r, const shortsc25519 *x); 51 | 52 | void sc25519_to32bytes(unsigned char r[32], const sc25519 *x); 53 | 54 | int sc25519_iszero_vartime(const sc25519 *x); 55 | 56 | int sc25519_isshort_vartime(const sc25519 *x); 57 | 58 | int sc25519_lt_vartime(const sc25519 *x, const sc25519 *y); 59 | 60 | void sc25519_add(sc25519 *r, const sc25519 *x, const sc25519 *y); 61 | 62 | void sc25519_sub_nored(sc25519 *r, const sc25519 *x, const sc25519 *y); 63 | 64 | void sc25519_mul(sc25519 *r, const sc25519 *x, const sc25519 *y); 65 | 66 | void sc25519_mul_shortsc(sc25519 *r, const sc25519 *x, const shortsc25519 *y); 67 | 68 | /* Convert s into a representation of the form \sum_{i=0}^{84}r[i]2^3 69 | * with r[i] in {-4,...,3} 70 | */ 71 | void sc25519_window3(signed char r[85], const sc25519 *s); 72 | 73 | /* Convert s into a representation of the form \sum_{i=0}^{50}r[i]2^5 74 | * with r[i] in {-16,...,15} 75 | */ 76 | void sc25519_window5(signed char r[51], const sc25519 *s); 77 | 78 | void sc25519_2interleave2(unsigned char r[127], const sc25519 *s1, const sc25519 *s2); 79 | 80 | #endif 81 | -------------------------------------------------------------------------------- /patched-src/mod_ed25519.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD: mod_ed25519.c,v 1.1 2014/01/08 05:00:01 tedu Exp $ */ 2 | 3 | /* 4 | * Public Domain, Authors: Daniel J. Bernstein, Niels Duif, Tanja Lange, 5 | * Peter Schwabe, Bo-Yin Yang. 6 | * Copied from supercop-20130419/crypto_sign/ed25519/ref/ed25519.c 7 | */ 8 | 9 | #include "crypto_api.h" 10 | 11 | #include "ge25519.h" 12 | 13 | static void get_hram(unsigned char *hram, const unsigned char *sm, const unsigned char *pk, unsigned char *playground, unsigned long long smlen) 14 | { 15 | unsigned long long i; 16 | 17 | for (i = 0;i < 32;++i) playground[i] = sm[i]; 18 | for (i = 32;i < 64;++i) playground[i] = pk[i-32]; 19 | for (i = 64;i < smlen;++i) playground[i] = sm[i]; 20 | 21 | crypto_hash_sha512(hram,playground,smlen); 22 | } 23 | 24 | #ifndef VERIFYONLY 25 | int crypto_sign_ed25519_keypair( 26 | unsigned char *pk, 27 | unsigned char *sk 28 | ) 29 | { 30 | sc25519 scsk; 31 | ge25519 gepk; 32 | unsigned char extsk[64]; 33 | int i; 34 | 35 | randombytes(sk, 32); 36 | crypto_hash_sha512(extsk, sk, 32); 37 | extsk[0] &= 248; 38 | extsk[31] &= 127; 39 | extsk[31] |= 64; 40 | 41 | sc25519_from32bytes(&scsk,extsk); 42 | 43 | ge25519_scalarmult_base(&gepk, &scsk); 44 | ge25519_pack(pk, &gepk); 45 | for(i=0;i<32;i++) 46 | sk[32 + i] = pk[i]; 47 | return 0; 48 | } 49 | 50 | int crypto_sign_ed25519( 51 | unsigned char *sm,unsigned long long *smlen, 52 | const unsigned char *m,unsigned long long mlen, 53 | const unsigned char *sk 54 | ) 55 | { 56 | sc25519 sck, scs, scsk; 57 | ge25519 ger; 58 | unsigned char r[32]; 59 | unsigned char s[32]; 60 | unsigned char extsk[64]; 61 | unsigned long long i; 62 | unsigned char hmg[crypto_hash_sha512_BYTES]; 63 | unsigned char hram[crypto_hash_sha512_BYTES]; 64 | 65 | crypto_hash_sha512(extsk, sk, 32); 66 | extsk[0] &= 248; 67 | extsk[31] &= 127; 68 | extsk[31] |= 64; 69 | 70 | *smlen = mlen+64; 71 | for(i=0;i 14 | -#include 15 | -#include 16 | -#include 17 | -#include 18 | +#include "mingw.h" 19 | 20 | #include 21 | -#include 22 | #include 23 | 24 | #include 25 | diff -Naur signify-obsd58/crypto_api.c signify-mingw/crypto_api.c 26 | --- signify-obsd58/crypto_api.c Sun Oct 18 22:11:29 2015 27 | +++ signify-mingw/crypto_api.c Sun Oct 18 22:09:37 2015 28 | @@ -3,6 +3,8 @@ 29 | * Public domain. Author: Ted Unangst 30 | * API compatible reimplementation of functions from nacl 31 | */ 32 | +#include "mingw.h" 33 | + 34 | #include 35 | 36 | #include 37 | diff -Naur signify-obsd58/err.c signify-mingw/err.c 38 | --- signify-obsd58/err.c Sun Oct 18 22:11:29 2015 39 | +++ signify-mingw/err.c Sun Oct 18 22:09:37 2015 40 | @@ -28,12 +28,11 @@ 41 | * SUCH DAMAGE. 42 | */ 43 | 44 | -#include 45 | #include 46 | 47 | /* PRINTFLIKE2 */ 48 | -__dead void 49 | -_err(int eval, const char *fmt, ...) 50 | +void 51 | +err(int eval, const char *fmt, ...) 52 | { 53 | va_list ap; 54 | 55 | @@ -41,7 +40,4 @@ 56 | _verr(eval, fmt, ap); 57 | va_end(ap); 58 | } 59 | - 60 | -/* PRINTFLIKE2 */ 61 | -__weak_alias(err, _err); 62 | 63 | diff -Naur signify-obsd58/errx.c signify-mingw/errx.c 64 | --- signify-obsd58/errx.c Sun Oct 18 22:11:29 2015 65 | +++ signify-mingw/errx.c Sun Oct 18 22:09:37 2015 66 | @@ -28,12 +28,11 @@ 67 | * SUCH DAMAGE. 68 | */ 69 | 70 | -#include 71 | #include 72 | 73 | /* PRINTFLIKE2 */ 74 | -__dead void 75 | -_errx(int eval, const char *fmt, ...) 76 | +void 77 | +errx(int eval, const char *fmt, ...) 78 | { 79 | va_list ap; 80 | 81 | @@ -41,7 +40,4 @@ 82 | _verrx(eval, fmt, ap); 83 | va_end(ap); 84 | } 85 | - 86 | -/* PRINTFLIKE2 */ 87 | -__weak_alias(errx, _errx); 88 | 89 | diff -Naur signify-obsd58/sha2.c signify-mingw/sha2.c 90 | --- signify-obsd58/sha2.c Sun Oct 18 22:11:29 2015 91 | +++ signify-mingw/sha2.c Sun Oct 18 22:09:37 2015 92 | @@ -34,6 +34,8 @@ 93 | * $From: sha2.c,v 1.1 2001/11/08 00:01:51 adg Exp adg $ 94 | */ 95 | 96 | +#include "mingw.h" 97 | + 98 | #include 99 | 100 | #include 101 | diff -Naur signify-obsd58/sha2.h signify-mingw/sha2.h 102 | --- signify-obsd58/sha2.h Sun Oct 18 22:11:29 2015 103 | +++ signify-mingw/sha2.h Sun Oct 18 22:09:37 2015 104 | @@ -63,7 +63,6 @@ 105 | u_int8_t buffer[SHA512_BLOCK_LENGTH]; 106 | } SHA2_CTX; 107 | 108 | -__BEGIN_DECLS 109 | void SHA224Init(SHA2_CTX *); 110 | void SHA224Transform(u_int32_t state[8], const u_int8_t [SHA224_BLOCK_LENGTH]); 111 | void SHA224Update(SHA2_CTX *, const u_int8_t *, size_t) 112 | @@ -131,6 +130,5 @@ 113 | char *SHA512Data(const u_int8_t *, size_t, char *) 114 | __attribute__((__bounded__(__string__,1,2))) 115 | __attribute__((__bounded__(__minbytes__,3,SHA512_DIGEST_STRING_LENGTH))); 116 | -__END_DECLS 117 | 118 | #endif /* _SHA2_H */ 119 | diff -Naur signify-obsd58/signify.c signify-mingw/signify.c 120 | --- signify-obsd58/signify.c Sun Oct 18 22:11:29 2015 121 | +++ signify-mingw/signify.c Sun Oct 18 22:09:37 2015 122 | @@ -14,11 +14,10 @@ 123 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 124 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 125 | */ 126 | +#include "mingw.h" 127 | + 128 | #include 129 | 130 | -#include 131 | -#include 132 | - 133 | #include 134 | #include 135 | #include 136 | @@ -26,11 +25,7 @@ 137 | #include 138 | #include 139 | #include 140 | -#include 141 | -#include 142 | #include 143 | -#include 144 | -#include 145 | #include 146 | 147 | #include "crypto_api.h" 148 | @@ -70,7 +65,7 @@ 149 | uint8_t sig[SIGBYTES]; 150 | }; 151 | 152 | -extern char *__progname; 153 | +char *__progname = "signify"; 154 | 155 | static void 156 | usage(const char *error) 157 | @@ -83,8 +78,7 @@ 158 | "\t%1$s -G [-n] [-c comment] -p pubkey -s seckey\n" 159 | "\t%1$s -S [-e] [-x sigfile] -s seckey -m message\n" 160 | #endif 161 | - "\t%1$s -V [-eq] [-x sigfile] -p pubkey -m message\n", 162 | - __progname); 163 | + "\tsignify -V [-eq] [-x sigfile] -p pubkey -m message\n"); 164 | exit(1); 165 | } 166 | 167 | diff -Naur signify-obsd58/verr.c signify-mingw/verr.c 168 | --- signify-obsd58/verr.c Sun Oct 18 22:11:29 2015 169 | +++ signify-mingw/verr.c Sun Oct 18 22:09:37 2015 170 | @@ -28,7 +28,6 @@ 171 | * SUCH DAMAGE. 172 | */ 173 | 174 | -#include 175 | #include 176 | #include 177 | #include 178 | @@ -37,7 +36,7 @@ 179 | 180 | extern char *__progname; /* Program name, from crt0. */ 181 | 182 | -__dead void 183 | +void 184 | _verr(int eval, const char *fmt, va_list ap) 185 | { 186 | int sverrno; 187 | @@ -51,6 +50,4 @@ 188 | (void)fprintf(stderr, "%s\n", strerror(sverrno)); 189 | exit(eval); 190 | } 191 | - 192 | -__weak_alias(verr, _verr); 193 | 194 | diff -Naur signify-obsd58/verrx.c signify-mingw/verrx.c 195 | --- signify-obsd58/verrx.c Sun Oct 18 22:11:29 2015 196 | +++ signify-mingw/verrx.c Sun Oct 18 22:09:37 2015 197 | @@ -28,14 +28,13 @@ 198 | * SUCH DAMAGE. 199 | */ 200 | 201 | -#include 202 | #include 203 | #include 204 | #include 205 | 206 | extern char *__progname; /* Program name, from crt0. */ 207 | 208 | -__dead void 209 | +void 210 | _verrx(int eval, const char *fmt, va_list ap) 211 | { 212 | (void)fprintf(stderr, "%s: ", __progname); 213 | @@ -44,6 +43,4 @@ 214 | (void)fprintf(stderr, "\n"); 215 | exit(eval); 216 | } 217 | - 218 | -__weak_alias(verrx, _verrx); 219 | 220 | -------------------------------------------------------------------------------- /patched-src/sha2.h: -------------------------------------------------------------------------------- 1 | /* $OpenBSD: sha2.h,v 1.9 2013/04/15 15:54:17 millert Exp $ */ 2 | 3 | /* 4 | * FILE: sha2.h 5 | * AUTHOR: Aaron D. Gifford 6 | * 7 | * Copyright (c) 2000-2001, Aaron D. Gifford 8 | * All rights reserved. 9 | * 10 | * Redistribution and use in source and binary forms, with or without 11 | * modification, are permitted provided that the following conditions 12 | * are met: 13 | * 1. Redistributions of source code must retain the above copyright 14 | * notice, this list of conditions and the following disclaimer. 15 | * 2. Redistributions in binary form must reproduce the above copyright 16 | * notice, this list of conditions and the following disclaimer in the 17 | * documentation and/or other materials provided with the distribution. 18 | * 3. Neither the name of the copyright holder nor the names of contributors 19 | * may be used to endorse or promote products derived from this software 20 | * without specific prior written permission. 21 | * 22 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND 23 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE 26 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 | * SUCH DAMAGE. 33 | * 34 | * $From: sha2.h,v 1.1 2001/11/08 00:02:01 adg Exp adg $ 35 | */ 36 | 37 | #ifndef _SHA2_H 38 | #define _SHA2_H 39 | 40 | 41 | /*** SHA-256/384/512 Various Length Definitions ***********************/ 42 | #define SHA224_BLOCK_LENGTH 64 43 | #define SHA224_DIGEST_LENGTH 28 44 | #define SHA224_DIGEST_STRING_LENGTH (SHA224_DIGEST_LENGTH * 2 + 1) 45 | #define SHA256_BLOCK_LENGTH 64 46 | #define SHA256_DIGEST_LENGTH 32 47 | #define SHA256_DIGEST_STRING_LENGTH (SHA256_DIGEST_LENGTH * 2 + 1) 48 | #define SHA384_BLOCK_LENGTH 128 49 | #define SHA384_DIGEST_LENGTH 48 50 | #define SHA384_DIGEST_STRING_LENGTH (SHA384_DIGEST_LENGTH * 2 + 1) 51 | #define SHA512_BLOCK_LENGTH 128 52 | #define SHA512_DIGEST_LENGTH 64 53 | #define SHA512_DIGEST_STRING_LENGTH (SHA512_DIGEST_LENGTH * 2 + 1) 54 | 55 | 56 | /*** SHA-224/256/384/512 Context Structure *******************************/ 57 | typedef struct _SHA2_CTX { 58 | union { 59 | u_int32_t st32[8]; 60 | u_int64_t st64[8]; 61 | } state; 62 | u_int64_t bitcount[2]; 63 | u_int8_t buffer[SHA512_BLOCK_LENGTH]; 64 | } SHA2_CTX; 65 | 66 | void SHA224Init(SHA2_CTX *); 67 | void SHA224Transform(u_int32_t state[8], const u_int8_t [SHA224_BLOCK_LENGTH]); 68 | void SHA224Update(SHA2_CTX *, const u_int8_t *, size_t) 69 | __attribute__((__bounded__(__string__,2,3))); 70 | void SHA224Pad(SHA2_CTX *); 71 | void SHA224Final(u_int8_t [SHA224_DIGEST_LENGTH], SHA2_CTX *) 72 | __attribute__((__bounded__(__minbytes__,1,SHA224_DIGEST_LENGTH))); 73 | char *SHA224End(SHA2_CTX *, char *) 74 | __attribute__((__bounded__(__minbytes__,2,SHA224_DIGEST_STRING_LENGTH))); 75 | char *SHA224File(const char *, char *) 76 | __attribute__((__bounded__(__minbytes__,2,SHA224_DIGEST_STRING_LENGTH))); 77 | char *SHA224FileChunk(const char *, char *, off_t, off_t) 78 | __attribute__((__bounded__(__minbytes__,2,SHA224_DIGEST_STRING_LENGTH))); 79 | char *SHA224Data(const u_int8_t *, size_t, char *) 80 | __attribute__((__bounded__(__string__,1,2))) 81 | __attribute__((__bounded__(__minbytes__,3,SHA224_DIGEST_STRING_LENGTH))); 82 | 83 | void SHA256Init(SHA2_CTX *); 84 | void SHA256Transform(u_int32_t state[8], const u_int8_t [SHA256_BLOCK_LENGTH]); 85 | void SHA256Update(SHA2_CTX *, const u_int8_t *, size_t) 86 | __attribute__((__bounded__(__string__,2,3))); 87 | void SHA256Pad(SHA2_CTX *); 88 | void SHA256Final(u_int8_t [SHA256_DIGEST_LENGTH], SHA2_CTX *) 89 | __attribute__((__bounded__(__minbytes__,1,SHA256_DIGEST_LENGTH))); 90 | char *SHA256End(SHA2_CTX *, char *) 91 | __attribute__((__bounded__(__minbytes__,2,SHA256_DIGEST_STRING_LENGTH))); 92 | char *SHA256File(const char *, char *) 93 | __attribute__((__bounded__(__minbytes__,2,SHA256_DIGEST_STRING_LENGTH))); 94 | char *SHA256FileChunk(const char *, char *, off_t, off_t) 95 | __attribute__((__bounded__(__minbytes__,2,SHA256_DIGEST_STRING_LENGTH))); 96 | char *SHA256Data(const u_int8_t *, size_t, char *) 97 | __attribute__((__bounded__(__string__,1,2))) 98 | __attribute__((__bounded__(__minbytes__,3,SHA256_DIGEST_STRING_LENGTH))); 99 | 100 | void SHA384Init(SHA2_CTX *); 101 | void SHA384Transform(u_int64_t state[8], const u_int8_t [SHA384_BLOCK_LENGTH]); 102 | void SHA384Update(SHA2_CTX *, const u_int8_t *, size_t) 103 | __attribute__((__bounded__(__string__,2,3))); 104 | void SHA384Pad(SHA2_CTX *); 105 | void SHA384Final(u_int8_t [SHA384_DIGEST_LENGTH], SHA2_CTX *) 106 | __attribute__((__bounded__(__minbytes__,1,SHA384_DIGEST_LENGTH))); 107 | char *SHA384End(SHA2_CTX *, char *) 108 | __attribute__((__bounded__(__minbytes__,2,SHA384_DIGEST_STRING_LENGTH))); 109 | char *SHA384File(const char *, char *) 110 | __attribute__((__bounded__(__minbytes__,2,SHA384_DIGEST_STRING_LENGTH))); 111 | char *SHA384FileChunk(const char *, char *, off_t, off_t) 112 | __attribute__((__bounded__(__minbytes__,2,SHA384_DIGEST_STRING_LENGTH))); 113 | char *SHA384Data(const u_int8_t *, size_t, char *) 114 | __attribute__((__bounded__(__string__,1,2))) 115 | __attribute__((__bounded__(__minbytes__,3,SHA384_DIGEST_STRING_LENGTH))); 116 | 117 | void SHA512Init(SHA2_CTX *); 118 | void SHA512Transform(u_int64_t state[8], const u_int8_t [SHA512_BLOCK_LENGTH]); 119 | void SHA512Update(SHA2_CTX *, const u_int8_t *, size_t) 120 | __attribute__((__bounded__(__string__,2,3))); 121 | void SHA512Pad(SHA2_CTX *); 122 | void SHA512Final(u_int8_t [SHA512_DIGEST_LENGTH], SHA2_CTX *) 123 | __attribute__((__bounded__(__minbytes__,1,SHA512_DIGEST_LENGTH))); 124 | char *SHA512End(SHA2_CTX *, char *) 125 | __attribute__((__bounded__(__minbytes__,2,SHA512_DIGEST_STRING_LENGTH))); 126 | char *SHA512File(const char *, char *) 127 | __attribute__((__bounded__(__minbytes__,2,SHA512_DIGEST_STRING_LENGTH))); 128 | char *SHA512FileChunk(const char *, char *, off_t, off_t) 129 | __attribute__((__bounded__(__minbytes__,2,SHA512_DIGEST_STRING_LENGTH))); 130 | char *SHA512Data(const u_int8_t *, size_t, char *) 131 | __attribute__((__bounded__(__string__,1,2))) 132 | __attribute__((__bounded__(__minbytes__,3,SHA512_DIGEST_STRING_LENGTH))); 133 | 134 | #endif /* _SHA2_H */ 135 | -------------------------------------------------------------------------------- /patched-src/smult_curve25519_ref.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD: smult_curve25519_ref.c,v 1.1 2014/07/22 00:41:19 deraadt Exp $ */ 2 | /* 3 | version 20081011 4 | Matthew Dempsky 5 | Public domain. 6 | Derived from public domain code by D. J. Bernstein. 7 | */ 8 | 9 | int crypto_scalarmult_curve25519(unsigned char *, const unsigned char *, const unsigned char *); 10 | 11 | static void add(unsigned int out[32],const unsigned int a[32],const unsigned int b[32]) 12 | { 13 | unsigned int j; 14 | unsigned int u; 15 | u = 0; 16 | for (j = 0;j < 31;++j) { u += a[j] + b[j]; out[j] = u & 255; u >>= 8; } 17 | u += a[31] + b[31]; out[31] = u; 18 | } 19 | 20 | static void sub(unsigned int out[32],const unsigned int a[32],const unsigned int b[32]) 21 | { 22 | unsigned int j; 23 | unsigned int u; 24 | u = 218; 25 | for (j = 0;j < 31;++j) { 26 | u += a[j] + 65280 - b[j]; 27 | out[j] = u & 255; 28 | u >>= 8; 29 | } 30 | u += a[31] - b[31]; 31 | out[31] = u; 32 | } 33 | 34 | static void squeeze(unsigned int a[32]) 35 | { 36 | unsigned int j; 37 | unsigned int u; 38 | u = 0; 39 | for (j = 0;j < 31;++j) { u += a[j]; a[j] = u & 255; u >>= 8; } 40 | u += a[31]; a[31] = u & 127; 41 | u = 19 * (u >> 7); 42 | for (j = 0;j < 31;++j) { u += a[j]; a[j] = u & 255; u >>= 8; } 43 | u += a[31]; a[31] = u; 44 | } 45 | 46 | static const unsigned int minusp[32] = { 47 | 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128 48 | } ; 49 | 50 | static void freeze(unsigned int a[32]) 51 | { 52 | unsigned int aorig[32]; 53 | unsigned int j; 54 | unsigned int negative; 55 | 56 | for (j = 0;j < 32;++j) aorig[j] = a[j]; 57 | add(a,a,minusp); 58 | negative = -((a[31] >> 7) & 1); 59 | for (j = 0;j < 32;++j) a[j] ^= negative & (aorig[j] ^ a[j]); 60 | } 61 | 62 | static void mult(unsigned int out[32],const unsigned int a[32],const unsigned int b[32]) 63 | { 64 | unsigned int i; 65 | unsigned int j; 66 | unsigned int u; 67 | 68 | for (i = 0;i < 32;++i) { 69 | u = 0; 70 | for (j = 0;j <= i;++j) u += a[j] * b[i - j]; 71 | for (j = i + 1;j < 32;++j) u += 38 * a[j] * b[i + 32 - j]; 72 | out[i] = u; 73 | } 74 | squeeze(out); 75 | } 76 | 77 | static void mult121665(unsigned int out[32],const unsigned int a[32]) 78 | { 79 | unsigned int j; 80 | unsigned int u; 81 | 82 | u = 0; 83 | for (j = 0;j < 31;++j) { u += 121665 * a[j]; out[j] = u & 255; u >>= 8; } 84 | u += 121665 * a[31]; out[31] = u & 127; 85 | u = 19 * (u >> 7); 86 | for (j = 0;j < 31;++j) { u += out[j]; out[j] = u & 255; u >>= 8; } 87 | u += out[j]; out[j] = u; 88 | } 89 | 90 | static void square(unsigned int out[32],const unsigned int a[32]) 91 | { 92 | unsigned int i; 93 | unsigned int j; 94 | unsigned int u; 95 | 96 | for (i = 0;i < 32;++i) { 97 | u = 0; 98 | for (j = 0;j < i - j;++j) u += a[j] * a[i - j]; 99 | for (j = i + 1;j < i + 32 - j;++j) u += 38 * a[j] * a[i + 32 - j]; 100 | u *= 2; 101 | if ((i & 1) == 0) { 102 | u += a[i / 2] * a[i / 2]; 103 | u += 38 * a[i / 2 + 16] * a[i / 2 + 16]; 104 | } 105 | out[i] = u; 106 | } 107 | squeeze(out); 108 | } 109 | 110 | static void select(unsigned int p[64],unsigned int q[64],const unsigned int r[64],const unsigned int s[64],unsigned int b) 111 | { 112 | unsigned int j; 113 | unsigned int t; 114 | unsigned int bminus1; 115 | 116 | bminus1 = b - 1; 117 | for (j = 0;j < 64;++j) { 118 | t = bminus1 & (r[j] ^ s[j]); 119 | p[j] = s[j] ^ t; 120 | q[j] = r[j] ^ t; 121 | } 122 | } 123 | 124 | static void mainloop(unsigned int work[64],const unsigned char e[32]) 125 | { 126 | unsigned int xzm1[64]; 127 | unsigned int xzm[64]; 128 | unsigned int xzmb[64]; 129 | unsigned int xzm1b[64]; 130 | unsigned int xznb[64]; 131 | unsigned int xzn1b[64]; 132 | unsigned int a0[64]; 133 | unsigned int a1[64]; 134 | unsigned int b0[64]; 135 | unsigned int b1[64]; 136 | unsigned int c1[64]; 137 | unsigned int r[32]; 138 | unsigned int s[32]; 139 | unsigned int t[32]; 140 | unsigned int u[32]; 141 | unsigned int j; 142 | unsigned int b; 143 | int pos; 144 | 145 | for (j = 0;j < 32;++j) xzm1[j] = work[j]; 146 | xzm1[32] = 1; 147 | for (j = 33;j < 64;++j) xzm1[j] = 0; 148 | 149 | xzm[0] = 1; 150 | for (j = 1;j < 64;++j) xzm[j] = 0; 151 | 152 | for (pos = 254;pos >= 0;--pos) { 153 | b = e[pos / 8] >> (pos & 7); 154 | b &= 1; 155 | select(xzmb,xzm1b,xzm,xzm1,b); 156 | add(a0,xzmb,xzmb + 32); 157 | sub(a0 + 32,xzmb,xzmb + 32); 158 | add(a1,xzm1b,xzm1b + 32); 159 | sub(a1 + 32,xzm1b,xzm1b + 32); 160 | square(b0,a0); 161 | square(b0 + 32,a0 + 32); 162 | mult(b1,a1,a0 + 32); 163 | mult(b1 + 32,a1 + 32,a0); 164 | add(c1,b1,b1 + 32); 165 | sub(c1 + 32,b1,b1 + 32); 166 | square(r,c1 + 32); 167 | sub(s,b0,b0 + 32); 168 | mult121665(t,s); 169 | add(u,t,b0); 170 | mult(xznb,b0,b0 + 32); 171 | mult(xznb + 32,s,u); 172 | square(xzn1b,c1); 173 | mult(xzn1b + 32,r,work); 174 | select(xzm,xzm1,xznb,xzn1b,b); 175 | } 176 | 177 | for (j = 0;j < 64;++j) work[j] = xzm[j]; 178 | } 179 | 180 | static void recip(unsigned int out[32],const unsigned int z[32]) 181 | { 182 | unsigned int z2[32]; 183 | unsigned int z9[32]; 184 | unsigned int z11[32]; 185 | unsigned int z2_5_0[32]; 186 | unsigned int z2_10_0[32]; 187 | unsigned int z2_20_0[32]; 188 | unsigned int z2_50_0[32]; 189 | unsigned int z2_100_0[32]; 190 | unsigned int t0[32]; 191 | unsigned int t1[32]; 192 | int i; 193 | 194 | /* 2 */ square(z2,z); 195 | /* 4 */ square(t1,z2); 196 | /* 8 */ square(t0,t1); 197 | /* 9 */ mult(z9,t0,z); 198 | /* 11 */ mult(z11,z9,z2); 199 | /* 22 */ square(t0,z11); 200 | /* 2^5 - 2^0 = 31 */ mult(z2_5_0,t0,z9); 201 | 202 | /* 2^6 - 2^1 */ square(t0,z2_5_0); 203 | /* 2^7 - 2^2 */ square(t1,t0); 204 | /* 2^8 - 2^3 */ square(t0,t1); 205 | /* 2^9 - 2^4 */ square(t1,t0); 206 | /* 2^10 - 2^5 */ square(t0,t1); 207 | /* 2^10 - 2^0 */ mult(z2_10_0,t0,z2_5_0); 208 | 209 | /* 2^11 - 2^1 */ square(t0,z2_10_0); 210 | /* 2^12 - 2^2 */ square(t1,t0); 211 | /* 2^20 - 2^10 */ for (i = 2;i < 10;i += 2) { square(t0,t1); square(t1,t0); } 212 | /* 2^20 - 2^0 */ mult(z2_20_0,t1,z2_10_0); 213 | 214 | /* 2^21 - 2^1 */ square(t0,z2_20_0); 215 | /* 2^22 - 2^2 */ square(t1,t0); 216 | /* 2^40 - 2^20 */ for (i = 2;i < 20;i += 2) { square(t0,t1); square(t1,t0); } 217 | /* 2^40 - 2^0 */ mult(t0,t1,z2_20_0); 218 | 219 | /* 2^41 - 2^1 */ square(t1,t0); 220 | /* 2^42 - 2^2 */ square(t0,t1); 221 | /* 2^50 - 2^10 */ for (i = 2;i < 10;i += 2) { square(t1,t0); square(t0,t1); } 222 | /* 2^50 - 2^0 */ mult(z2_50_0,t0,z2_10_0); 223 | 224 | /* 2^51 - 2^1 */ square(t0,z2_50_0); 225 | /* 2^52 - 2^2 */ square(t1,t0); 226 | /* 2^100 - 2^50 */ for (i = 2;i < 50;i += 2) { square(t0,t1); square(t1,t0); } 227 | /* 2^100 - 2^0 */ mult(z2_100_0,t1,z2_50_0); 228 | 229 | /* 2^101 - 2^1 */ square(t1,z2_100_0); 230 | /* 2^102 - 2^2 */ square(t0,t1); 231 | /* 2^200 - 2^100 */ for (i = 2;i < 100;i += 2) { square(t1,t0); square(t0,t1); } 232 | /* 2^200 - 2^0 */ mult(t1,t0,z2_100_0); 233 | 234 | /* 2^201 - 2^1 */ square(t0,t1); 235 | /* 2^202 - 2^2 */ square(t1,t0); 236 | /* 2^250 - 2^50 */ for (i = 2;i < 50;i += 2) { square(t0,t1); square(t1,t0); } 237 | /* 2^250 - 2^0 */ mult(t0,t1,z2_50_0); 238 | 239 | /* 2^251 - 2^1 */ square(t1,t0); 240 | /* 2^252 - 2^2 */ square(t0,t1); 241 | /* 2^253 - 2^3 */ square(t1,t0); 242 | /* 2^254 - 2^4 */ square(t0,t1); 243 | /* 2^255 - 2^5 */ square(t1,t0); 244 | /* 2^255 - 21 */ mult(out,t1,z11); 245 | } 246 | 247 | int crypto_scalarmult_curve25519(unsigned char *q, 248 | const unsigned char *n, 249 | const unsigned char *p) 250 | { 251 | unsigned int work[96]; 252 | unsigned char e[32]; 253 | unsigned int i; 254 | for (i = 0;i < 32;++i) e[i] = n[i]; 255 | e[0] &= 248; 256 | e[31] &= 127; 257 | e[31] |= 64; 258 | for (i = 0;i < 32;++i) work[i] = p[i]; 259 | mainloop(work,e); 260 | recip(work + 32,work + 32); 261 | mult(work + 64,work,work + 32); 262 | freeze(work + 64); 263 | for (i = 0;i < 32;++i) q[i] = work[64 + i]; 264 | return 0; 265 | } 266 | -------------------------------------------------------------------------------- /patched-src/sc25519.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD: sc25519.c,v 1.1 2014/07/22 00:41:19 deraadt Exp $ */ 2 | 3 | /* 4 | * Public Domain, Authors: Daniel J. Bernstein, Niels Duif, Tanja Lange, 5 | * Peter Schwabe, Bo-Yin Yang. 6 | * Copied from supercop-20130419/crypto_sign/ed25519/ref/sc25519.c 7 | */ 8 | 9 | #include "sc25519.h" 10 | 11 | /*Arithmetic modulo the group order m = 2^252 + 27742317777372353535851937790883648493 = 7237005577332262213973186563042994240857116359379907606001950938285454250989 */ 12 | 13 | static const crypto_uint32 m[32] = {0xED, 0xD3, 0xF5, 0x5C, 0x1A, 0x63, 0x12, 0x58, 0xD6, 0x9C, 0xF7, 0xA2, 0xDE, 0xF9, 0xDE, 0x14, 14 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}; 15 | 16 | static const crypto_uint32 mu[33] = {0x1B, 0x13, 0x2C, 0x0A, 0xA3, 0xE5, 0x9C, 0xED, 0xA7, 0x29, 0x63, 0x08, 0x5D, 0x21, 0x06, 0x21, 17 | 0xEB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F}; 18 | 19 | static crypto_uint32 lt(crypto_uint32 a,crypto_uint32 b) /* 16-bit inputs */ 20 | { 21 | unsigned int x = a; 22 | x -= (unsigned int) b; /* 0..65535: no; 4294901761..4294967295: yes */ 23 | x >>= 31; /* 0: no; 1: yes */ 24 | return x; 25 | } 26 | 27 | /* Reduce coefficients of r before calling reduce_add_sub */ 28 | static void reduce_add_sub(sc25519 *r) 29 | { 30 | crypto_uint32 pb = 0; 31 | crypto_uint32 b; 32 | crypto_uint32 mask; 33 | int i; 34 | unsigned char t[32]; 35 | 36 | for(i=0;i<32;i++) 37 | { 38 | pb += m[i]; 39 | b = lt(r->v[i],pb); 40 | t[i] = r->v[i]-pb+(b<<8); 41 | pb = b; 42 | } 43 | mask = b - 1; 44 | for(i=0;i<32;i++) 45 | r->v[i] ^= mask & (r->v[i] ^ t[i]); 46 | } 47 | 48 | /* Reduce coefficients of x before calling barrett_reduce */ 49 | static void barrett_reduce(sc25519 *r, const crypto_uint32 x[64]) 50 | { 51 | /* See HAC, Alg. 14.42 */ 52 | int i,j; 53 | crypto_uint32 q2[66]; 54 | crypto_uint32 *q3 = q2 + 33; 55 | crypto_uint32 r1[33]; 56 | crypto_uint32 r2[33]; 57 | crypto_uint32 carry; 58 | crypto_uint32 pb = 0; 59 | crypto_uint32 b; 60 | 61 | for (i = 0;i < 66;++i) q2[i] = 0; 62 | for (i = 0;i < 33;++i) r2[i] = 0; 63 | 64 | for(i=0;i<33;i++) 65 | for(j=0;j<33;j++) 66 | if(i+j >= 31) q2[i+j] += mu[i]*x[j+31]; 67 | carry = q2[31] >> 8; 68 | q2[32] += carry; 69 | carry = q2[32] >> 8; 70 | q2[33] += carry; 71 | 72 | for(i=0;i<33;i++)r1[i] = x[i]; 73 | for(i=0;i<32;i++) 74 | for(j=0;j<33;j++) 75 | if(i+j < 33) r2[i+j] += m[i]*q3[j]; 76 | 77 | for(i=0;i<32;i++) 78 | { 79 | carry = r2[i] >> 8; 80 | r2[i+1] += carry; 81 | r2[i] &= 0xff; 82 | } 83 | 84 | for(i=0;i<32;i++) 85 | { 86 | pb += r2[i]; 87 | b = lt(r1[i],pb); 88 | r->v[i] = r1[i]-pb+(b<<8); 89 | pb = b; 90 | } 91 | 92 | /* XXX: Can it really happen that r<0?, See HAC, Alg 14.42, Step 3 93 | * If so: Handle it here! 94 | */ 95 | 96 | reduce_add_sub(r); 97 | reduce_add_sub(r); 98 | } 99 | 100 | void sc25519_from32bytes(sc25519 *r, const unsigned char x[32]) 101 | { 102 | int i; 103 | crypto_uint32 t[64]; 104 | for(i=0;i<32;i++) t[i] = x[i]; 105 | for(i=32;i<64;++i) t[i] = 0; 106 | barrett_reduce(r, t); 107 | } 108 | 109 | void shortsc25519_from16bytes(shortsc25519 *r, const unsigned char x[16]) 110 | { 111 | int i; 112 | for(i=0;i<16;i++) r->v[i] = x[i]; 113 | } 114 | 115 | void sc25519_from64bytes(sc25519 *r, const unsigned char x[64]) 116 | { 117 | int i; 118 | crypto_uint32 t[64]; 119 | for(i=0;i<64;i++) t[i] = x[i]; 120 | barrett_reduce(r, t); 121 | } 122 | 123 | void sc25519_from_shortsc(sc25519 *r, const shortsc25519 *x) 124 | { 125 | int i; 126 | for(i=0;i<16;i++) 127 | r->v[i] = x->v[i]; 128 | for(i=0;i<16;i++) 129 | r->v[16+i] = 0; 130 | } 131 | 132 | void sc25519_to32bytes(unsigned char r[32], const sc25519 *x) 133 | { 134 | int i; 135 | for(i=0;i<32;i++) r[i] = x->v[i]; 136 | } 137 | 138 | int sc25519_iszero_vartime(const sc25519 *x) 139 | { 140 | int i; 141 | for(i=0;i<32;i++) 142 | if(x->v[i] != 0) return 0; 143 | return 1; 144 | } 145 | 146 | int sc25519_isshort_vartime(const sc25519 *x) 147 | { 148 | int i; 149 | for(i=31;i>15;i--) 150 | if(x->v[i] != 0) return 0; 151 | return 1; 152 | } 153 | 154 | int sc25519_lt_vartime(const sc25519 *x, const sc25519 *y) 155 | { 156 | int i; 157 | for(i=31;i>=0;i--) 158 | { 159 | if(x->v[i] < y->v[i]) return 1; 160 | if(x->v[i] > y->v[i]) return 0; 161 | } 162 | return 0; 163 | } 164 | 165 | void sc25519_add(sc25519 *r, const sc25519 *x, const sc25519 *y) 166 | { 167 | int i, carry; 168 | for(i=0;i<32;i++) r->v[i] = x->v[i] + y->v[i]; 169 | for(i=0;i<31;i++) 170 | { 171 | carry = r->v[i] >> 8; 172 | r->v[i+1] += carry; 173 | r->v[i] &= 0xff; 174 | } 175 | reduce_add_sub(r); 176 | } 177 | 178 | void sc25519_sub_nored(sc25519 *r, const sc25519 *x, const sc25519 *y) 179 | { 180 | crypto_uint32 b = 0; 181 | crypto_uint32 t; 182 | int i; 183 | for(i=0;i<32;i++) 184 | { 185 | t = x->v[i] - y->v[i] - b; 186 | r->v[i] = t & 255; 187 | b = (t >> 8) & 1; 188 | } 189 | } 190 | 191 | void sc25519_mul(sc25519 *r, const sc25519 *x, const sc25519 *y) 192 | { 193 | int i,j,carry; 194 | crypto_uint32 t[64]; 195 | for(i=0;i<64;i++)t[i] = 0; 196 | 197 | for(i=0;i<32;i++) 198 | for(j=0;j<32;j++) 199 | t[i+j] += x->v[i] * y->v[j]; 200 | 201 | /* Reduce coefficients */ 202 | for(i=0;i<63;i++) 203 | { 204 | carry = t[i] >> 8; 205 | t[i+1] += carry; 206 | t[i] &= 0xff; 207 | } 208 | 209 | barrett_reduce(r, t); 210 | } 211 | 212 | void sc25519_mul_shortsc(sc25519 *r, const sc25519 *x, const shortsc25519 *y) 213 | { 214 | sc25519 t; 215 | sc25519_from_shortsc(&t, y); 216 | sc25519_mul(r, x, &t); 217 | } 218 | 219 | void sc25519_window3(signed char r[85], const sc25519 *s) 220 | { 221 | char carry; 222 | int i; 223 | for(i=0;i<10;i++) 224 | { 225 | r[8*i+0] = s->v[3*i+0] & 7; 226 | r[8*i+1] = (s->v[3*i+0] >> 3) & 7; 227 | r[8*i+2] = (s->v[3*i+0] >> 6) & 7; 228 | r[8*i+2] ^= (s->v[3*i+1] << 2) & 7; 229 | r[8*i+3] = (s->v[3*i+1] >> 1) & 7; 230 | r[8*i+4] = (s->v[3*i+1] >> 4) & 7; 231 | r[8*i+5] = (s->v[3*i+1] >> 7) & 7; 232 | r[8*i+5] ^= (s->v[3*i+2] << 1) & 7; 233 | r[8*i+6] = (s->v[3*i+2] >> 2) & 7; 234 | r[8*i+7] = (s->v[3*i+2] >> 5) & 7; 235 | } 236 | r[8*i+0] = s->v[3*i+0] & 7; 237 | r[8*i+1] = (s->v[3*i+0] >> 3) & 7; 238 | r[8*i+2] = (s->v[3*i+0] >> 6) & 7; 239 | r[8*i+2] ^= (s->v[3*i+1] << 2) & 7; 240 | r[8*i+3] = (s->v[3*i+1] >> 1) & 7; 241 | r[8*i+4] = (s->v[3*i+1] >> 4) & 7; 242 | 243 | /* Making it signed */ 244 | carry = 0; 245 | for(i=0;i<84;i++) 246 | { 247 | r[i] += carry; 248 | r[i+1] += r[i] >> 3; 249 | r[i] &= 7; 250 | carry = r[i] >> 2; 251 | r[i] -= carry<<3; 252 | } 253 | r[84] += carry; 254 | } 255 | 256 | void sc25519_window5(signed char r[51], const sc25519 *s) 257 | { 258 | char carry; 259 | int i; 260 | for(i=0;i<6;i++) 261 | { 262 | r[8*i+0] = s->v[5*i+0] & 31; 263 | r[8*i+1] = (s->v[5*i+0] >> 5) & 31; 264 | r[8*i+1] ^= (s->v[5*i+1] << 3) & 31; 265 | r[8*i+2] = (s->v[5*i+1] >> 2) & 31; 266 | r[8*i+3] = (s->v[5*i+1] >> 7) & 31; 267 | r[8*i+3] ^= (s->v[5*i+2] << 1) & 31; 268 | r[8*i+4] = (s->v[5*i+2] >> 4) & 31; 269 | r[8*i+4] ^= (s->v[5*i+3] << 4) & 31; 270 | r[8*i+5] = (s->v[5*i+3] >> 1) & 31; 271 | r[8*i+6] = (s->v[5*i+3] >> 6) & 31; 272 | r[8*i+6] ^= (s->v[5*i+4] << 2) & 31; 273 | r[8*i+7] = (s->v[5*i+4] >> 3) & 31; 274 | } 275 | r[8*i+0] = s->v[5*i+0] & 31; 276 | r[8*i+1] = (s->v[5*i+0] >> 5) & 31; 277 | r[8*i+1] ^= (s->v[5*i+1] << 3) & 31; 278 | r[8*i+2] = (s->v[5*i+1] >> 2) & 31; 279 | 280 | /* Making it signed */ 281 | carry = 0; 282 | for(i=0;i<50;i++) 283 | { 284 | r[i] += carry; 285 | r[i+1] += r[i] >> 5; 286 | r[i] &= 31; 287 | carry = r[i] >> 4; 288 | r[i] -= carry<<5; 289 | } 290 | r[50] += carry; 291 | } 292 | 293 | void sc25519_2interleave2(unsigned char r[127], const sc25519 *s1, const sc25519 *s2) 294 | { 295 | int i; 296 | for(i=0;i<31;i++) 297 | { 298 | r[4*i] = ( s1->v[i] & 3) ^ (( s2->v[i] & 3) << 2); 299 | r[4*i+1] = ((s1->v[i] >> 2) & 3) ^ (((s2->v[i] >> 2) & 3) << 2); 300 | r[4*i+2] = ((s1->v[i] >> 4) & 3) ^ (((s2->v[i] >> 4) & 3) << 2); 301 | r[4*i+3] = ((s1->v[i] >> 6) & 3) ^ (((s2->v[i] >> 6) & 3) << 2); 302 | } 303 | r[124] = ( s1->v[31] & 3) ^ (( s2->v[31] & 3) << 2); 304 | r[125] = ((s1->v[31] >> 2) & 3) ^ (((s2->v[31] >> 2) & 3) << 2); 305 | r[126] = ((s1->v[31] >> 4) & 3) ^ (((s2->v[31] >> 4) & 3) << 2); 306 | } 307 | -------------------------------------------------------------------------------- /patched-src/fe25519.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD: fe25519.c,v 1.1 2014/07/22 00:41:19 deraadt Exp $ */ 2 | 3 | /* 4 | * Public Domain, Authors: Daniel J. Bernstein, Niels Duif, Tanja Lange, 5 | * Peter Schwabe, Bo-Yin Yang. 6 | * Copied from supercop-20130419/crypto_sign/ed25519/ref/fe25519.c 7 | */ 8 | 9 | #define WINDOWSIZE 1 /* Should be 1,2, or 4 */ 10 | #define WINDOWMASK ((1<>= 31; /* 1: yes; 0: no */ 19 | return x; 20 | } 21 | 22 | static crypto_uint32 ge(crypto_uint32 a,crypto_uint32 b) /* 16-bit inputs */ 23 | { 24 | unsigned int x = a; 25 | x -= (unsigned int) b; /* 0..65535: yes; 4294901761..4294967295: no */ 26 | x >>= 31; /* 0: yes; 1: no */ 27 | x ^= 1; /* 1: yes; 0: no */ 28 | return x; 29 | } 30 | 31 | static crypto_uint32 times19(crypto_uint32 a) 32 | { 33 | return (a << 4) + (a << 1) + a; 34 | } 35 | 36 | static crypto_uint32 times38(crypto_uint32 a) 37 | { 38 | return (a << 5) + (a << 2) + (a << 1); 39 | } 40 | 41 | static void reduce_add_sub(fe25519 *r) 42 | { 43 | crypto_uint32 t; 44 | int i,rep; 45 | 46 | for(rep=0;rep<4;rep++) 47 | { 48 | t = r->v[31] >> 7; 49 | r->v[31] &= 127; 50 | t = times19(t); 51 | r->v[0] += t; 52 | for(i=0;i<31;i++) 53 | { 54 | t = r->v[i] >> 8; 55 | r->v[i+1] += t; 56 | r->v[i] &= 255; 57 | } 58 | } 59 | } 60 | 61 | static void reduce_mul(fe25519 *r) 62 | { 63 | crypto_uint32 t; 64 | int i,rep; 65 | 66 | for(rep=0;rep<2;rep++) 67 | { 68 | t = r->v[31] >> 7; 69 | r->v[31] &= 127; 70 | t = times19(t); 71 | r->v[0] += t; 72 | for(i=0;i<31;i++) 73 | { 74 | t = r->v[i] >> 8; 75 | r->v[i+1] += t; 76 | r->v[i] &= 255; 77 | } 78 | } 79 | } 80 | 81 | /* reduction modulo 2^255-19 */ 82 | void fe25519_freeze(fe25519 *r) 83 | { 84 | int i; 85 | crypto_uint32 m = equal(r->v[31],127); 86 | for(i=30;i>0;i--) 87 | m &= equal(r->v[i],255); 88 | m &= ge(r->v[0],237); 89 | 90 | m = -m; 91 | 92 | r->v[31] -= m&127; 93 | for(i=30;i>0;i--) 94 | r->v[i] -= m&255; 95 | r->v[0] -= m&237; 96 | } 97 | 98 | void fe25519_unpack(fe25519 *r, const unsigned char x[32]) 99 | { 100 | int i; 101 | for(i=0;i<32;i++) r->v[i] = x[i]; 102 | r->v[31] &= 127; 103 | } 104 | 105 | /* Assumes input x being reduced below 2^255 */ 106 | void fe25519_pack(unsigned char r[32], const fe25519 *x) 107 | { 108 | int i; 109 | fe25519 y = *x; 110 | fe25519_freeze(&y); 111 | for(i=0;i<32;i++) 112 | r[i] = y.v[i]; 113 | } 114 | 115 | int fe25519_iszero(const fe25519 *x) 116 | { 117 | int i; 118 | int r; 119 | fe25519 t = *x; 120 | fe25519_freeze(&t); 121 | r = equal(t.v[0],0); 122 | for(i=1;i<32;i++) 123 | r &= equal(t.v[i],0); 124 | return r; 125 | } 126 | 127 | int fe25519_iseq_vartime(const fe25519 *x, const fe25519 *y) 128 | { 129 | int i; 130 | fe25519 t1 = *x; 131 | fe25519 t2 = *y; 132 | fe25519_freeze(&t1); 133 | fe25519_freeze(&t2); 134 | for(i=0;i<32;i++) 135 | if(t1.v[i] != t2.v[i]) return 0; 136 | return 1; 137 | } 138 | 139 | void fe25519_cmov(fe25519 *r, const fe25519 *x, unsigned char b) 140 | { 141 | int i; 142 | crypto_uint32 mask = b; 143 | mask = -mask; 144 | for(i=0;i<32;i++) r->v[i] ^= mask & (x->v[i] ^ r->v[i]); 145 | } 146 | 147 | unsigned char fe25519_getparity(const fe25519 *x) 148 | { 149 | fe25519 t = *x; 150 | fe25519_freeze(&t); 151 | return t.v[0] & 1; 152 | } 153 | 154 | void fe25519_setone(fe25519 *r) 155 | { 156 | int i; 157 | r->v[0] = 1; 158 | for(i=1;i<32;i++) r->v[i]=0; 159 | } 160 | 161 | void fe25519_setzero(fe25519 *r) 162 | { 163 | int i; 164 | for(i=0;i<32;i++) r->v[i]=0; 165 | } 166 | 167 | void fe25519_neg(fe25519 *r, const fe25519 *x) 168 | { 169 | fe25519 t; 170 | int i; 171 | for(i=0;i<32;i++) t.v[i]=x->v[i]; 172 | fe25519_setzero(r); 173 | fe25519_sub(r, r, &t); 174 | } 175 | 176 | void fe25519_add(fe25519 *r, const fe25519 *x, const fe25519 *y) 177 | { 178 | int i; 179 | for(i=0;i<32;i++) r->v[i] = x->v[i] + y->v[i]; 180 | reduce_add_sub(r); 181 | } 182 | 183 | void fe25519_sub(fe25519 *r, const fe25519 *x, const fe25519 *y) 184 | { 185 | int i; 186 | crypto_uint32 t[32]; 187 | t[0] = x->v[0] + 0x1da; 188 | t[31] = x->v[31] + 0xfe; 189 | for(i=1;i<31;i++) t[i] = x->v[i] + 0x1fe; 190 | for(i=0;i<32;i++) r->v[i] = t[i] - y->v[i]; 191 | reduce_add_sub(r); 192 | } 193 | 194 | void fe25519_mul(fe25519 *r, const fe25519 *x, const fe25519 *y) 195 | { 196 | int i,j; 197 | crypto_uint32 t[63]; 198 | for(i=0;i<63;i++)t[i] = 0; 199 | 200 | for(i=0;i<32;i++) 201 | for(j=0;j<32;j++) 202 | t[i+j] += x->v[i] * y->v[j]; 203 | 204 | for(i=32;i<63;i++) 205 | r->v[i-32] = t[i-32] + times38(t[i]); 206 | r->v[31] = t[31]; /* result now in r[0]...r[31] */ 207 | 208 | reduce_mul(r); 209 | } 210 | 211 | void fe25519_square(fe25519 *r, const fe25519 *x) 212 | { 213 | fe25519_mul(r, x, x); 214 | } 215 | 216 | void fe25519_invert(fe25519 *r, const fe25519 *x) 217 | { 218 | fe25519 z2; 219 | fe25519 z9; 220 | fe25519 z11; 221 | fe25519 z2_5_0; 222 | fe25519 z2_10_0; 223 | fe25519 z2_20_0; 224 | fe25519 z2_50_0; 225 | fe25519 z2_100_0; 226 | fe25519 t0; 227 | fe25519 t1; 228 | int i; 229 | 230 | /* 2 */ fe25519_square(&z2,x); 231 | /* 4 */ fe25519_square(&t1,&z2); 232 | /* 8 */ fe25519_square(&t0,&t1); 233 | /* 9 */ fe25519_mul(&z9,&t0,x); 234 | /* 11 */ fe25519_mul(&z11,&z9,&z2); 235 | /* 22 */ fe25519_square(&t0,&z11); 236 | /* 2^5 - 2^0 = 31 */ fe25519_mul(&z2_5_0,&t0,&z9); 237 | 238 | /* 2^6 - 2^1 */ fe25519_square(&t0,&z2_5_0); 239 | /* 2^7 - 2^2 */ fe25519_square(&t1,&t0); 240 | /* 2^8 - 2^3 */ fe25519_square(&t0,&t1); 241 | /* 2^9 - 2^4 */ fe25519_square(&t1,&t0); 242 | /* 2^10 - 2^5 */ fe25519_square(&t0,&t1); 243 | /* 2^10 - 2^0 */ fe25519_mul(&z2_10_0,&t0,&z2_5_0); 244 | 245 | /* 2^11 - 2^1 */ fe25519_square(&t0,&z2_10_0); 246 | /* 2^12 - 2^2 */ fe25519_square(&t1,&t0); 247 | /* 2^20 - 2^10 */ for (i = 2;i < 10;i += 2) { fe25519_square(&t0,&t1); fe25519_square(&t1,&t0); } 248 | /* 2^20 - 2^0 */ fe25519_mul(&z2_20_0,&t1,&z2_10_0); 249 | 250 | /* 2^21 - 2^1 */ fe25519_square(&t0,&z2_20_0); 251 | /* 2^22 - 2^2 */ fe25519_square(&t1,&t0); 252 | /* 2^40 - 2^20 */ for (i = 2;i < 20;i += 2) { fe25519_square(&t0,&t1); fe25519_square(&t1,&t0); } 253 | /* 2^40 - 2^0 */ fe25519_mul(&t0,&t1,&z2_20_0); 254 | 255 | /* 2^41 - 2^1 */ fe25519_square(&t1,&t0); 256 | /* 2^42 - 2^2 */ fe25519_square(&t0,&t1); 257 | /* 2^50 - 2^10 */ for (i = 2;i < 10;i += 2) { fe25519_square(&t1,&t0); fe25519_square(&t0,&t1); } 258 | /* 2^50 - 2^0 */ fe25519_mul(&z2_50_0,&t0,&z2_10_0); 259 | 260 | /* 2^51 - 2^1 */ fe25519_square(&t0,&z2_50_0); 261 | /* 2^52 - 2^2 */ fe25519_square(&t1,&t0); 262 | /* 2^100 - 2^50 */ for (i = 2;i < 50;i += 2) { fe25519_square(&t0,&t1); fe25519_square(&t1,&t0); } 263 | /* 2^100 - 2^0 */ fe25519_mul(&z2_100_0,&t1,&z2_50_0); 264 | 265 | /* 2^101 - 2^1 */ fe25519_square(&t1,&z2_100_0); 266 | /* 2^102 - 2^2 */ fe25519_square(&t0,&t1); 267 | /* 2^200 - 2^100 */ for (i = 2;i < 100;i += 2) { fe25519_square(&t1,&t0); fe25519_square(&t0,&t1); } 268 | /* 2^200 - 2^0 */ fe25519_mul(&t1,&t0,&z2_100_0); 269 | 270 | /* 2^201 - 2^1 */ fe25519_square(&t0,&t1); 271 | /* 2^202 - 2^2 */ fe25519_square(&t1,&t0); 272 | /* 2^250 - 2^50 */ for (i = 2;i < 50;i += 2) { fe25519_square(&t0,&t1); fe25519_square(&t1,&t0); } 273 | /* 2^250 - 2^0 */ fe25519_mul(&t0,&t1,&z2_50_0); 274 | 275 | /* 2^251 - 2^1 */ fe25519_square(&t1,&t0); 276 | /* 2^252 - 2^2 */ fe25519_square(&t0,&t1); 277 | /* 2^253 - 2^3 */ fe25519_square(&t1,&t0); 278 | /* 2^254 - 2^4 */ fe25519_square(&t0,&t1); 279 | /* 2^255 - 2^5 */ fe25519_square(&t1,&t0); 280 | /* 2^255 - 21 */ fe25519_mul(r,&t1,&z11); 281 | } 282 | 283 | void fe25519_pow2523(fe25519 *r, const fe25519 *x) 284 | { 285 | fe25519 z2; 286 | fe25519 z9; 287 | fe25519 z11; 288 | fe25519 z2_5_0; 289 | fe25519 z2_10_0; 290 | fe25519 z2_20_0; 291 | fe25519 z2_50_0; 292 | fe25519 z2_100_0; 293 | fe25519 t; 294 | int i; 295 | 296 | /* 2 */ fe25519_square(&z2,x); 297 | /* 4 */ fe25519_square(&t,&z2); 298 | /* 8 */ fe25519_square(&t,&t); 299 | /* 9 */ fe25519_mul(&z9,&t,x); 300 | /* 11 */ fe25519_mul(&z11,&z9,&z2); 301 | /* 22 */ fe25519_square(&t,&z11); 302 | /* 2^5 - 2^0 = 31 */ fe25519_mul(&z2_5_0,&t,&z9); 303 | 304 | /* 2^6 - 2^1 */ fe25519_square(&t,&z2_5_0); 305 | /* 2^10 - 2^5 */ for (i = 1;i < 5;i++) { fe25519_square(&t,&t); } 306 | /* 2^10 - 2^0 */ fe25519_mul(&z2_10_0,&t,&z2_5_0); 307 | 308 | /* 2^11 - 2^1 */ fe25519_square(&t,&z2_10_0); 309 | /* 2^20 - 2^10 */ for (i = 1;i < 10;i++) { fe25519_square(&t,&t); } 310 | /* 2^20 - 2^0 */ fe25519_mul(&z2_20_0,&t,&z2_10_0); 311 | 312 | /* 2^21 - 2^1 */ fe25519_square(&t,&z2_20_0); 313 | /* 2^40 - 2^20 */ for (i = 1;i < 20;i++) { fe25519_square(&t,&t); } 314 | /* 2^40 - 2^0 */ fe25519_mul(&t,&t,&z2_20_0); 315 | 316 | /* 2^41 - 2^1 */ fe25519_square(&t,&t); 317 | /* 2^50 - 2^10 */ for (i = 1;i < 10;i++) { fe25519_square(&t,&t); } 318 | /* 2^50 - 2^0 */ fe25519_mul(&z2_50_0,&t,&z2_10_0); 319 | 320 | /* 2^51 - 2^1 */ fe25519_square(&t,&z2_50_0); 321 | /* 2^100 - 2^50 */ for (i = 1;i < 50;i++) { fe25519_square(&t,&t); } 322 | /* 2^100 - 2^0 */ fe25519_mul(&z2_100_0,&t,&z2_50_0); 323 | 324 | /* 2^101 - 2^1 */ fe25519_square(&t,&z2_100_0); 325 | /* 2^200 - 2^100 */ for (i = 1;i < 100;i++) { fe25519_square(&t,&t); } 326 | /* 2^200 - 2^0 */ fe25519_mul(&t,&t,&z2_100_0); 327 | 328 | /* 2^201 - 2^1 */ fe25519_square(&t,&t); 329 | /* 2^250 - 2^50 */ for (i = 1;i < 50;i++) { fe25519_square(&t,&t); } 330 | /* 2^250 - 2^0 */ fe25519_mul(&t,&t,&z2_50_0); 331 | 332 | /* 2^251 - 2^1 */ fe25519_square(&t,&t); 333 | /* 2^252 - 2^2 */ fe25519_square(&t,&t); 334 | /* 2^252 - 3 */ fe25519_mul(r,&t,x); 335 | } 336 | -------------------------------------------------------------------------------- /patched-src/base64.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD: base64.c,v 1.8 2015/01/16 16:48:51 deraadt Exp $ */ 2 | 3 | /* 4 | * Copyright (c) 1996 by Internet Software Consortium. 5 | * 6 | * Permission to use, copy, modify, and distribute this software for any 7 | * purpose with or without fee is hereby granted, provided that the above 8 | * copyright notice and this permission notice appear in all copies. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS 11 | * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES 12 | * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE 13 | * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 14 | * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 15 | * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS 16 | * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 17 | * SOFTWARE. 18 | */ 19 | 20 | /* 21 | * Portions Copyright (c) 1995 by International Business Machines, Inc. 22 | * 23 | * International Business Machines, Inc. (hereinafter called IBM) grants 24 | * permission under its copyrights to use, copy, modify, and distribute this 25 | * Software with or without fee, provided that the above copyright notice and 26 | * all paragraphs of this notice appear in all copies, and that the name of IBM 27 | * not be used in connection with the marketing of any product incorporating 28 | * the Software or modifications thereof, without specific, written prior 29 | * permission. 30 | * 31 | * To the extent it has a right to do so, IBM grants an immunity from suit 32 | * under its patents, if any, for the use, sale or manufacture of products to 33 | * the extent that such products are used for performing Domain Name System 34 | * dynamic updates in TCP/IP networks by means of the Software. No immunity is 35 | * granted for any product per se or for any other function of any product. 36 | * 37 | * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES, 38 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 39 | * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, 40 | * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING 41 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN 42 | * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES. 43 | */ 44 | 45 | #include "mingw.h" 46 | 47 | #include 48 | #include 49 | 50 | #include 51 | #include 52 | 53 | static const char Base64[] = 54 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 55 | static const char Pad64 = '='; 56 | 57 | /* (From RFC1521 and draft-ietf-dnssec-secext-03.txt) 58 | The following encoding technique is taken from RFC 1521 by Borenstein 59 | and Freed. It is reproduced here in a slightly edited form for 60 | convenience. 61 | 62 | A 65-character subset of US-ASCII is used, enabling 6 bits to be 63 | represented per printable character. (The extra 65th character, "=", 64 | is used to signify a special processing function.) 65 | 66 | The encoding process represents 24-bit groups of input bits as output 67 | strings of 4 encoded characters. Proceeding from left to right, a 68 | 24-bit input group is formed by concatenating 3 8-bit input groups. 69 | These 24 bits are then treated as 4 concatenated 6-bit groups, each 70 | of which is translated into a single digit in the base64 alphabet. 71 | 72 | Each 6-bit group is used as an index into an array of 64 printable 73 | characters. The character referenced by the index is placed in the 74 | output string. 75 | 76 | Table 1: The Base64 Alphabet 77 | 78 | Value Encoding Value Encoding Value Encoding Value Encoding 79 | 0 A 17 R 34 i 51 z 80 | 1 B 18 S 35 j 52 0 81 | 2 C 19 T 36 k 53 1 82 | 3 D 20 U 37 l 54 2 83 | 4 E 21 V 38 m 55 3 84 | 5 F 22 W 39 n 56 4 85 | 6 G 23 X 40 o 57 5 86 | 7 H 24 Y 41 p 58 6 87 | 8 I 25 Z 42 q 59 7 88 | 9 J 26 a 43 r 60 8 89 | 10 K 27 b 44 s 61 9 90 | 11 L 28 c 45 t 62 + 91 | 12 M 29 d 46 u 63 / 92 | 13 N 30 e 47 v 93 | 14 O 31 f 48 w (pad) = 94 | 15 P 32 g 49 x 95 | 16 Q 33 h 50 y 96 | 97 | Special processing is performed if fewer than 24 bits are available 98 | at the end of the data being encoded. A full encoding quantum is 99 | always completed at the end of a quantity. When fewer than 24 input 100 | bits are available in an input group, zero bits are added (on the 101 | right) to form an integral number of 6-bit groups. Padding at the 102 | end of the data is performed using the '=' character. 103 | 104 | Since all base64 input is an integral number of octets, only the 105 | ------------------------------------------------- 106 | following cases can arise: 107 | 108 | (1) the final quantum of encoding input is an integral 109 | multiple of 24 bits; here, the final unit of encoded 110 | output will be an integral multiple of 4 characters 111 | with no "=" padding, 112 | (2) the final quantum of encoding input is exactly 8 bits; 113 | here, the final unit of encoded output will be two 114 | characters followed by two "=" padding characters, or 115 | (3) the final quantum of encoding input is exactly 16 bits; 116 | here, the final unit of encoded output will be three 117 | characters followed by one "=" padding character. 118 | */ 119 | 120 | int 121 | b64_ntop(src, srclength, target, targsize) 122 | u_char const *src; 123 | size_t srclength; 124 | char *target; 125 | size_t targsize; 126 | { 127 | size_t datalength = 0; 128 | u_char input[3]; 129 | u_char output[4]; 130 | int i; 131 | 132 | while (2 < srclength) { 133 | input[0] = *src++; 134 | input[1] = *src++; 135 | input[2] = *src++; 136 | srclength -= 3; 137 | 138 | output[0] = input[0] >> 2; 139 | output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); 140 | output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); 141 | output[3] = input[2] & 0x3f; 142 | 143 | if (datalength + 4 > targsize) 144 | return (-1); 145 | target[datalength++] = Base64[output[0]]; 146 | target[datalength++] = Base64[output[1]]; 147 | target[datalength++] = Base64[output[2]]; 148 | target[datalength++] = Base64[output[3]]; 149 | } 150 | 151 | /* Now we worry about padding. */ 152 | if (0 != srclength) { 153 | /* Get what's left. */ 154 | input[0] = input[1] = input[2] = '\0'; 155 | for (i = 0; i < srclength; i++) 156 | input[i] = *src++; 157 | 158 | output[0] = input[0] >> 2; 159 | output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); 160 | output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); 161 | 162 | if (datalength + 4 > targsize) 163 | return (-1); 164 | target[datalength++] = Base64[output[0]]; 165 | target[datalength++] = Base64[output[1]]; 166 | if (srclength == 1) 167 | target[datalength++] = Pad64; 168 | else 169 | target[datalength++] = Base64[output[2]]; 170 | target[datalength++] = Pad64; 171 | } 172 | if (datalength >= targsize) 173 | return (-1); 174 | target[datalength] = '\0'; /* Returned value doesn't count \0. */ 175 | return (datalength); 176 | } 177 | 178 | /* skips all whitespace anywhere. 179 | converts characters, four at a time, starting at (or after) 180 | src from base - 64 numbers into three 8 bit bytes in the target area. 181 | it returns the number of data bytes stored at the target, or -1 on error. 182 | */ 183 | 184 | int 185 | b64_pton(src, target, targsize) 186 | char const *src; 187 | u_char *target; 188 | size_t targsize; 189 | { 190 | int tarindex, state, ch; 191 | u_char nextbyte; 192 | char *pos; 193 | 194 | state = 0; 195 | tarindex = 0; 196 | 197 | while ((ch = (unsigned char)*src++) != '\0') { 198 | if (isspace(ch)) /* Skip whitespace anywhere. */ 199 | continue; 200 | 201 | if (ch == Pad64) 202 | break; 203 | 204 | pos = strchr(Base64, ch); 205 | if (pos == 0) /* A non-base64 character. */ 206 | return (-1); 207 | 208 | switch (state) { 209 | case 0: 210 | if (target) { 211 | if (tarindex >= targsize) 212 | return (-1); 213 | target[tarindex] = (pos - Base64) << 2; 214 | } 215 | state = 1; 216 | break; 217 | case 1: 218 | if (target) { 219 | if (tarindex >= targsize) 220 | return (-1); 221 | target[tarindex] |= (pos - Base64) >> 4; 222 | nextbyte = ((pos - Base64) & 0x0f) << 4; 223 | if (tarindex + 1 < targsize) 224 | target[tarindex+1] = nextbyte; 225 | else if (nextbyte) 226 | return (-1); 227 | } 228 | tarindex++; 229 | state = 2; 230 | break; 231 | case 2: 232 | if (target) { 233 | if (tarindex >= targsize) 234 | return (-1); 235 | target[tarindex] |= (pos - Base64) >> 2; 236 | nextbyte = ((pos - Base64) & 0x03) << 6; 237 | if (tarindex + 1 < targsize) 238 | target[tarindex+1] = nextbyte; 239 | else if (nextbyte) 240 | return (-1); 241 | } 242 | tarindex++; 243 | state = 3; 244 | break; 245 | case 3: 246 | if (target) { 247 | if (tarindex >= targsize) 248 | return (-1); 249 | target[tarindex] |= (pos - Base64); 250 | } 251 | tarindex++; 252 | state = 0; 253 | break; 254 | } 255 | } 256 | 257 | /* 258 | * We are done decoding Base-64 chars. Let's see if we ended 259 | * on a byte boundary, and/or with erroneous trailing characters. 260 | */ 261 | 262 | if (ch == Pad64) { /* We got a pad char. */ 263 | ch = (unsigned char)*src++; /* Skip it, get next. */ 264 | switch (state) { 265 | case 0: /* Invalid = in first position */ 266 | case 1: /* Invalid = in second position */ 267 | return (-1); 268 | 269 | case 2: /* Valid, means one byte of info */ 270 | /* Skip any number of spaces. */ 271 | for (; ch != '\0'; ch = (unsigned char)*src++) 272 | if (!isspace(ch)) 273 | break; 274 | /* Make sure there is another trailing = sign. */ 275 | if (ch != Pad64) 276 | return (-1); 277 | ch = (unsigned char)*src++; /* Skip the = */ 278 | /* Fall through to "single trailing =" case. */ 279 | /* FALLTHROUGH */ 280 | 281 | case 3: /* Valid, means two bytes of info */ 282 | /* 283 | * We know this char is an =. Is there anything but 284 | * whitespace after it? 285 | */ 286 | for (; ch != '\0'; ch = (unsigned char)*src++) 287 | if (!isspace(ch)) 288 | return (-1); 289 | 290 | /* 291 | * Now make sure for cases 2 and 3 that the "extra" 292 | * bits that slopped past the last full byte were 293 | * zeros. If we don't check them, they become a 294 | * subliminal channel. 295 | */ 296 | if (target && tarindex < targsize && 297 | target[tarindex] != 0) 298 | return (-1); 299 | } 300 | } else { 301 | /* 302 | * We ended by seeing the end of the string. Make sure we 303 | * have no partial bytes lying around. 304 | */ 305 | if (state != 0) 306 | return (-1); 307 | } 308 | 309 | return (tarindex); 310 | } 311 | -------------------------------------------------------------------------------- /patched-src/mod_ge25519.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD: mod_ge25519.c,v 1.2 2014/01/08 05:51:35 deraadt Exp $ */ 2 | 3 | /* 4 | * Public Domain, Authors: Daniel J. Bernstein, Niels Duif, Tanja Lange, 5 | * Peter Schwabe, Bo-Yin Yang. 6 | * Copied from supercop-20130419/crypto_sign/ed25519/ref/ge25519.c 7 | */ 8 | 9 | #include "fe25519.h" 10 | #include "sc25519.h" 11 | #include "ge25519.h" 12 | 13 | /* 14 | * Arithmetic on the twisted Edwards curve -x^2 + y^2 = 1 + dx^2y^2 15 | * with d = -(121665/121666) = 37095705934669439343138083508754565189542113879843219016388785533085940283555 16 | * Base point: (15112221349535400772501151409588531511454012693041857206046113283949847762202,46316835694926478169428394003475163141307993866256225615783033603165251855960); 17 | */ 18 | 19 | /* d */ 20 | static const fe25519 ge25519_ecd = {{0xA3, 0x78, 0x59, 0x13, 0xCA, 0x4D, 0xEB, 0x75, 0xAB, 0xD8, 0x41, 0x41, 0x4D, 0x0A, 0x70, 0x00, 21 | 0x98, 0xE8, 0x79, 0x77, 0x79, 0x40, 0xC7, 0x8C, 0x73, 0xFE, 0x6F, 0x2B, 0xEE, 0x6C, 0x03, 0x52}}; 22 | /* 2*d */ 23 | static const fe25519 ge25519_ec2d = {{0x59, 0xF1, 0xB2, 0x26, 0x94, 0x9B, 0xD6, 0xEB, 0x56, 0xB1, 0x83, 0x82, 0x9A, 0x14, 0xE0, 0x00, 24 | 0x30, 0xD1, 0xF3, 0xEE, 0xF2, 0x80, 0x8E, 0x19, 0xE7, 0xFC, 0xDF, 0x56, 0xDC, 0xD9, 0x06, 0x24}}; 25 | /* sqrt(-1) */ 26 | static const fe25519 ge25519_sqrtm1 = {{0xB0, 0xA0, 0x0E, 0x4A, 0x27, 0x1B, 0xEE, 0xC4, 0x78, 0xE4, 0x2F, 0xAD, 0x06, 0x18, 0x43, 0x2F, 27 | 0xA7, 0xD7, 0xFB, 0x3D, 0x99, 0x00, 0x4D, 0x2B, 0x0B, 0xDF, 0xC1, 0x4F, 0x80, 0x24, 0x83, 0x2B}}; 28 | 29 | #define ge25519_p3 ge25519 30 | 31 | typedef struct 32 | { 33 | fe25519 x; 34 | fe25519 z; 35 | fe25519 y; 36 | fe25519 t; 37 | } ge25519_p1p1; 38 | 39 | typedef struct 40 | { 41 | fe25519 x; 42 | fe25519 y; 43 | fe25519 z; 44 | } ge25519_p2; 45 | 46 | typedef struct 47 | { 48 | fe25519 x; 49 | fe25519 y; 50 | } ge25519_aff; 51 | 52 | 53 | /* Packed coordinates of the base point */ 54 | const ge25519 ge25519_base = {{{0x1A, 0xD5, 0x25, 0x8F, 0x60, 0x2D, 0x56, 0xC9, 0xB2, 0xA7, 0x25, 0x95, 0x60, 0xC7, 0x2C, 0x69, 55 | 0x5C, 0xDC, 0xD6, 0xFD, 0x31, 0xE2, 0xA4, 0xC0, 0xFE, 0x53, 0x6E, 0xCD, 0xD3, 0x36, 0x69, 0x21}}, 56 | {{0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 57 | 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66}}, 58 | {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 59 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, 60 | {{0xA3, 0xDD, 0xB7, 0xA5, 0xB3, 0x8A, 0xDE, 0x6D, 0xF5, 0x52, 0x51, 0x77, 0x80, 0x9F, 0xF0, 0x20, 61 | 0x7D, 0xE3, 0xAB, 0x64, 0x8E, 0x4E, 0xEA, 0x66, 0x65, 0x76, 0x8B, 0xD7, 0x0F, 0x5F, 0x87, 0x67}}}; 62 | 63 | #ifndef VERIFYONLY 64 | /* Multiples of the base point in affine representation */ 65 | static const ge25519_aff ge25519_base_multiples_affine[425] = { 66 | #include "ge25519_base.data" 67 | }; 68 | #endif 69 | 70 | static void p1p1_to_p2(ge25519_p2 *r, const ge25519_p1p1 *p) 71 | { 72 | fe25519_mul(&r->x, &p->x, &p->t); 73 | fe25519_mul(&r->y, &p->y, &p->z); 74 | fe25519_mul(&r->z, &p->z, &p->t); 75 | } 76 | 77 | static void p1p1_to_p3(ge25519_p3 *r, const ge25519_p1p1 *p) 78 | { 79 | p1p1_to_p2((ge25519_p2 *)r, p); 80 | fe25519_mul(&r->t, &p->x, &p->y); 81 | } 82 | 83 | #ifndef VERIFYONLY 84 | static void ge25519_mixadd2(ge25519_p3 *r, const ge25519_aff *q) 85 | { 86 | fe25519 a,b,t1,t2,c,d,e,f,g,h,qt; 87 | fe25519_mul(&qt, &q->x, &q->y); 88 | fe25519_sub(&a, &r->y, &r->x); /* A = (Y1-X1)*(Y2-X2) */ 89 | fe25519_add(&b, &r->y, &r->x); /* B = (Y1+X1)*(Y2+X2) */ 90 | fe25519_sub(&t1, &q->y, &q->x); 91 | fe25519_add(&t2, &q->y, &q->x); 92 | fe25519_mul(&a, &a, &t1); 93 | fe25519_mul(&b, &b, &t2); 94 | fe25519_sub(&e, &b, &a); /* E = B-A */ 95 | fe25519_add(&h, &b, &a); /* H = B+A */ 96 | fe25519_mul(&c, &r->t, &qt); /* C = T1*k*T2 */ 97 | fe25519_mul(&c, &c, &ge25519_ec2d); 98 | fe25519_add(&d, &r->z, &r->z); /* D = Z1*2 */ 99 | fe25519_sub(&f, &d, &c); /* F = D-C */ 100 | fe25519_add(&g, &d, &c); /* G = D+C */ 101 | fe25519_mul(&r->x, &e, &f); 102 | fe25519_mul(&r->y, &h, &g); 103 | fe25519_mul(&r->z, &g, &f); 104 | fe25519_mul(&r->t, &e, &h); 105 | } 106 | #endif 107 | 108 | static void add_p1p1(ge25519_p1p1 *r, const ge25519_p3 *p, const ge25519_p3 *q) 109 | { 110 | fe25519 a, b, c, d, t; 111 | 112 | fe25519_sub(&a, &p->y, &p->x); /* A = (Y1-X1)*(Y2-X2) */ 113 | fe25519_sub(&t, &q->y, &q->x); 114 | fe25519_mul(&a, &a, &t); 115 | fe25519_add(&b, &p->x, &p->y); /* B = (Y1+X1)*(Y2+X2) */ 116 | fe25519_add(&t, &q->x, &q->y); 117 | fe25519_mul(&b, &b, &t); 118 | fe25519_mul(&c, &p->t, &q->t); /* C = T1*k*T2 */ 119 | fe25519_mul(&c, &c, &ge25519_ec2d); 120 | fe25519_mul(&d, &p->z, &q->z); /* D = Z1*2*Z2 */ 121 | fe25519_add(&d, &d, &d); 122 | fe25519_sub(&r->x, &b, &a); /* E = B-A */ 123 | fe25519_sub(&r->t, &d, &c); /* F = D-C */ 124 | fe25519_add(&r->z, &d, &c); /* G = D+C */ 125 | fe25519_add(&r->y, &b, &a); /* H = B+A */ 126 | } 127 | 128 | /* See http://www.hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html#doubling-dbl-2008-hwcd */ 129 | static void dbl_p1p1(ge25519_p1p1 *r, const ge25519_p2 *p) 130 | { 131 | fe25519 a,b,c,d; 132 | fe25519_square(&a, &p->x); 133 | fe25519_square(&b, &p->y); 134 | fe25519_square(&c, &p->z); 135 | fe25519_add(&c, &c, &c); 136 | fe25519_neg(&d, &a); 137 | 138 | fe25519_add(&r->x, &p->x, &p->y); 139 | fe25519_square(&r->x, &r->x); 140 | fe25519_sub(&r->x, &r->x, &a); 141 | fe25519_sub(&r->x, &r->x, &b); 142 | fe25519_add(&r->z, &d, &b); 143 | fe25519_sub(&r->t, &r->z, &c); 144 | fe25519_sub(&r->y, &d, &b); 145 | } 146 | 147 | #ifndef VERIFYONLY 148 | /* Constant-time version of: if(b) r = p */ 149 | static void cmov_aff(ge25519_aff *r, const ge25519_aff *p, unsigned char b) 150 | { 151 | fe25519_cmov(&r->x, &p->x, b); 152 | fe25519_cmov(&r->y, &p->y, b); 153 | } 154 | 155 | static unsigned char equal(signed char b,signed char c) 156 | { 157 | unsigned char ub = b; 158 | unsigned char uc = c; 159 | unsigned char x = ub ^ uc; /* 0: yes; 1..255: no */ 160 | crypto_uint32 y = x; /* 0: yes; 1..255: no */ 161 | y -= 1; /* 4294967295: yes; 0..254: no */ 162 | y >>= 31; /* 1: yes; 0: no */ 163 | return y; 164 | } 165 | 166 | static unsigned char negative(signed char b) 167 | { 168 | unsigned long long x = b; /* 18446744073709551361..18446744073709551615: yes; 0..255: no */ 169 | x >>= 63; /* 1: yes; 0: no */ 170 | return x; 171 | } 172 | 173 | static void choose_t(ge25519_aff *t, unsigned long long pos, signed char b) 174 | { 175 | /* constant time */ 176 | fe25519 v; 177 | *t = ge25519_base_multiples_affine[5*pos+0]; 178 | cmov_aff(t, &ge25519_base_multiples_affine[5*pos+1],equal(b,1) | equal(b,-1)); 179 | cmov_aff(t, &ge25519_base_multiples_affine[5*pos+2],equal(b,2) | equal(b,-2)); 180 | cmov_aff(t, &ge25519_base_multiples_affine[5*pos+3],equal(b,3) | equal(b,-3)); 181 | cmov_aff(t, &ge25519_base_multiples_affine[5*pos+4],equal(b,-4)); 182 | fe25519_neg(&v, &t->x); 183 | fe25519_cmov(&t->x, &v, negative(b)); 184 | } 185 | #endif 186 | 187 | static void setneutral(ge25519 *r) 188 | { 189 | fe25519_setzero(&r->x); 190 | fe25519_setone(&r->y); 191 | fe25519_setone(&r->z); 192 | fe25519_setzero(&r->t); 193 | } 194 | 195 | /* ******************************************************************** 196 | * EXPORTED FUNCTIONS 197 | ******************************************************************** */ 198 | 199 | /* return 0 on success, -1 otherwise */ 200 | int ge25519_unpackneg_vartime(ge25519_p3 *r, const unsigned char p[32]) 201 | { 202 | unsigned char par; 203 | fe25519 t, chk, num, den, den2, den4, den6; 204 | fe25519_setone(&r->z); 205 | par = p[31] >> 7; 206 | fe25519_unpack(&r->y, p); 207 | fe25519_square(&num, &r->y); /* x = y^2 */ 208 | fe25519_mul(&den, &num, &ge25519_ecd); /* den = dy^2 */ 209 | fe25519_sub(&num, &num, &r->z); /* x = y^2-1 */ 210 | fe25519_add(&den, &r->z, &den); /* den = dy^2+1 */ 211 | 212 | /* Computation of sqrt(num/den) */ 213 | /* 1.: computation of num^((p-5)/8)*den^((7p-35)/8) = (num*den^7)^((p-5)/8) */ 214 | fe25519_square(&den2, &den); 215 | fe25519_square(&den4, &den2); 216 | fe25519_mul(&den6, &den4, &den2); 217 | fe25519_mul(&t, &den6, &num); 218 | fe25519_mul(&t, &t, &den); 219 | 220 | fe25519_pow2523(&t, &t); 221 | /* 2. computation of r->x = t * num * den^3 */ 222 | fe25519_mul(&t, &t, &num); 223 | fe25519_mul(&t, &t, &den); 224 | fe25519_mul(&t, &t, &den); 225 | fe25519_mul(&r->x, &t, &den); 226 | 227 | /* 3. Check whether sqrt computation gave correct result, multiply by sqrt(-1) if not: */ 228 | fe25519_square(&chk, &r->x); 229 | fe25519_mul(&chk, &chk, &den); 230 | if (!fe25519_iseq_vartime(&chk, &num)) 231 | fe25519_mul(&r->x, &r->x, &ge25519_sqrtm1); 232 | 233 | /* 4. Now we have one of the two square roots, except if input was not a square */ 234 | fe25519_square(&chk, &r->x); 235 | fe25519_mul(&chk, &chk, &den); 236 | if (!fe25519_iseq_vartime(&chk, &num)) 237 | return -1; 238 | 239 | /* 5. Choose the desired square root according to parity: */ 240 | if(fe25519_getparity(&r->x) != (1-par)) 241 | fe25519_neg(&r->x, &r->x); 242 | 243 | fe25519_mul(&r->t, &r->x, &r->y); 244 | return 0; 245 | } 246 | 247 | void ge25519_pack(unsigned char r[32], const ge25519_p3 *p) 248 | { 249 | fe25519 tx, ty, zi; 250 | fe25519_invert(&zi, &p->z); 251 | fe25519_mul(&tx, &p->x, &zi); 252 | fe25519_mul(&ty, &p->y, &zi); 253 | fe25519_pack(r, &ty); 254 | r[31] ^= fe25519_getparity(&tx) << 7; 255 | } 256 | 257 | int ge25519_isneutral_vartime(const ge25519_p3 *p) 258 | { 259 | int ret = 1; 260 | if(!fe25519_iszero(&p->x)) ret = 0; 261 | if(!fe25519_iseq_vartime(&p->y, &p->z)) ret = 0; 262 | return ret; 263 | } 264 | 265 | /* computes [s1]p1 + [s2]p2 */ 266 | void ge25519_double_scalarmult_vartime(ge25519_p3 *r, const ge25519_p3 *p1, const sc25519 *s1, const ge25519_p3 *p2, const sc25519 *s2) 267 | { 268 | ge25519_p1p1 tp1p1; 269 | ge25519_p3 pre[16]; 270 | unsigned char b[127]; 271 | int i; 272 | 273 | /* precomputation s2 s1 */ 274 | setneutral(pre); /* 00 00 */ 275 | pre[1] = *p1; /* 00 01 */ 276 | dbl_p1p1(&tp1p1,(ge25519_p2 *)p1); p1p1_to_p3( &pre[2], &tp1p1); /* 00 10 */ 277 | add_p1p1(&tp1p1,&pre[1], &pre[2]); p1p1_to_p3( &pre[3], &tp1p1); /* 00 11 */ 278 | pre[4] = *p2; /* 01 00 */ 279 | add_p1p1(&tp1p1,&pre[1], &pre[4]); p1p1_to_p3( &pre[5], &tp1p1); /* 01 01 */ 280 | add_p1p1(&tp1p1,&pre[2], &pre[4]); p1p1_to_p3( &pre[6], &tp1p1); /* 01 10 */ 281 | add_p1p1(&tp1p1,&pre[3], &pre[4]); p1p1_to_p3( &pre[7], &tp1p1); /* 01 11 */ 282 | dbl_p1p1(&tp1p1,(ge25519_p2 *)p2); p1p1_to_p3( &pre[8], &tp1p1); /* 10 00 */ 283 | add_p1p1(&tp1p1,&pre[1], &pre[8]); p1p1_to_p3( &pre[9], &tp1p1); /* 10 01 */ 284 | dbl_p1p1(&tp1p1,(ge25519_p2 *)&pre[5]); p1p1_to_p3(&pre[10], &tp1p1); /* 10 10 */ 285 | add_p1p1(&tp1p1,&pre[3], &pre[8]); p1p1_to_p3(&pre[11], &tp1p1); /* 10 11 */ 286 | add_p1p1(&tp1p1,&pre[4], &pre[8]); p1p1_to_p3(&pre[12], &tp1p1); /* 11 00 */ 287 | add_p1p1(&tp1p1,&pre[1],&pre[12]); p1p1_to_p3(&pre[13], &tp1p1); /* 11 01 */ 288 | add_p1p1(&tp1p1,&pre[2],&pre[12]); p1p1_to_p3(&pre[14], &tp1p1); /* 11 10 */ 289 | add_p1p1(&tp1p1,&pre[3],&pre[12]); p1p1_to_p3(&pre[15], &tp1p1); /* 11 11 */ 290 | 291 | sc25519_2interleave2(b,s1,s2); 292 | 293 | /* scalar multiplication */ 294 | *r = pre[b[126]]; 295 | for(i=125;i>=0;i--) 296 | { 297 | dbl_p1p1(&tp1p1, (ge25519_p2 *)r); 298 | p1p1_to_p2((ge25519_p2 *) r, &tp1p1); 299 | dbl_p1p1(&tp1p1, (ge25519_p2 *)r); 300 | if(b[i]!=0) 301 | { 302 | p1p1_to_p3(r, &tp1p1); 303 | add_p1p1(&tp1p1, r, &pre[b[i]]); 304 | } 305 | if(i != 0) p1p1_to_p2((ge25519_p2 *)r, &tp1p1); 306 | else p1p1_to_p3(r, &tp1p1); 307 | } 308 | } 309 | 310 | #ifndef VERIFYONLY 311 | void ge25519_scalarmult_base(ge25519_p3 *r, const sc25519 *s) 312 | { 313 | signed char b[85]; 314 | int i; 315 | ge25519_aff t; 316 | sc25519_window3(b,s); 317 | 318 | choose_t((ge25519_aff *)r, 0, b[0]); 319 | fe25519_setone(&r->z); 320 | fe25519_mul(&r->t, &r->x, &r->y); 321 | for(i=1;i<85;i++) 322 | { 323 | choose_t(&t, (unsigned long long) i, b[i]); 324 | ge25519_mixadd2(r, &t); 325 | } 326 | } 327 | #endif 328 | -------------------------------------------------------------------------------- /patched-src/signify.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD: signify.c,v 1.100 2015/01/16 06:16:12 tedu Exp $ */ 2 | /* 3 | * Copyright (c) 2013 Ted Unangst 4 | * 5 | * Permission to use, copy, modify, and distribute this software for any 6 | * purpose with or without fee is hereby granted, provided that the above 7 | * copyright notice and this permission notice appear in all copies. 8 | * 9 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 | */ 17 | #include "mingw.h" 18 | 19 | #include 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #include "crypto_api.h" 32 | 33 | #define SIGBYTES crypto_sign_ed25519_BYTES 34 | #define SECRETBYTES crypto_sign_ed25519_SECRETKEYBYTES 35 | #define PUBLICBYTES crypto_sign_ed25519_PUBLICKEYBYTES 36 | 37 | #define PKALG "Ed" 38 | #define KDFALG "BK" 39 | #define KEYNUMLEN 8 40 | 41 | #define COMMENTHDR "untrusted comment: " 42 | #define COMMENTHDRLEN 19 43 | #define COMMENTMAXLEN 1024 44 | #define VERIFYWITH "verify with " 45 | 46 | struct enckey { 47 | uint8_t pkalg[2]; 48 | uint8_t kdfalg[2]; 49 | uint32_t kdfrounds; 50 | uint8_t salt[16]; 51 | uint8_t checksum[8]; 52 | uint8_t keynum[KEYNUMLEN]; 53 | uint8_t seckey[SECRETBYTES]; 54 | }; 55 | 56 | struct pubkey { 57 | uint8_t pkalg[2]; 58 | uint8_t keynum[KEYNUMLEN]; 59 | uint8_t pubkey[PUBLICBYTES]; 60 | }; 61 | 62 | struct sig { 63 | uint8_t pkalg[2]; 64 | uint8_t keynum[KEYNUMLEN]; 65 | uint8_t sig[SIGBYTES]; 66 | }; 67 | 68 | char *__progname = "signify"; 69 | 70 | static void 71 | usage(const char *error) 72 | { 73 | if (error) 74 | fprintf(stderr, "%s\n", error); 75 | fprintf(stderr, "usage:" 76 | #ifndef VERIFYONLY 77 | "\t%1$s -C [-q] -p pubkey -x sigfile [file ...]\n" 78 | "\t%1$s -G [-n] [-c comment] -p pubkey -s seckey\n" 79 | "\t%1$s -S [-e] [-x sigfile] -s seckey -m message\n" 80 | #endif 81 | "\tsignify -V [-eq] [-x sigfile] -p pubkey -m message\n"); 82 | exit(1); 83 | } 84 | 85 | static int 86 | xopen(const char *fname, int oflags, mode_t mode) 87 | { 88 | struct stat sb; 89 | int fd; 90 | 91 | if (strcmp(fname, "-") == 0) { 92 | if ((oflags & O_WRONLY)) 93 | fd = dup(STDOUT_FILENO); 94 | else 95 | fd = dup(STDIN_FILENO); 96 | if (fd == -1) 97 | err(1, "dup failed"); 98 | } else { 99 | fd = open(fname, oflags, mode); 100 | if (fd == -1) 101 | err(1, "can't open %s for %s", fname, 102 | (oflags & O_WRONLY) ? "writing" : "reading"); 103 | } 104 | if (fstat(fd, &sb) == -1 || S_ISDIR(sb.st_mode)) 105 | errx(1, "not a valid file: %s", fname); 106 | return fd; 107 | } 108 | 109 | static void * 110 | xmalloc(size_t len) 111 | { 112 | void *p; 113 | 114 | if (!(p = malloc(len))) 115 | err(1, "malloc %zu", len); 116 | return p; 117 | } 118 | 119 | static size_t 120 | parseb64file(const char *filename, char *b64, void *buf, size_t buflen, 121 | char *comment) 122 | { 123 | char *commentend, *b64end; 124 | 125 | commentend = strchr(b64, '\n'); 126 | if (!commentend || commentend - b64 <= COMMENTHDRLEN || 127 | memcmp(b64, COMMENTHDR, COMMENTHDRLEN) != 0) 128 | errx(1, "invalid comment in %s; must start with '%s'", 129 | filename, COMMENTHDR); 130 | *commentend = '\0'; 131 | if (comment) { 132 | if (strlcpy(comment, b64 + COMMENTHDRLEN, 133 | COMMENTMAXLEN) >= COMMENTMAXLEN) 134 | errx(1, "comment too long"); 135 | } 136 | if (!(b64end = strchr(commentend + 1, '\n'))) 137 | errx(1, "missing new line after base64 in %s", filename); 138 | *b64end = '\0'; 139 | if (b64_pton(commentend + 1, buf, buflen) != buflen) 140 | errx(1, "invalid base64 encoding in %s", filename); 141 | if (memcmp(buf, PKALG, 2) != 0) 142 | errx(1, "unsupported file %s", filename); 143 | return b64end - b64 + 1; 144 | } 145 | 146 | static void 147 | readb64file(const char *filename, void *buf, size_t buflen, char *comment) 148 | { 149 | char b64[2048]; 150 | int rv, fd; 151 | 152 | fd = xopen(filename, O_RDONLY | O_NOFOLLOW, 0); 153 | if ((rv = read(fd, b64, sizeof(b64) - 1)) == -1) 154 | err(1, "read from %s", filename); 155 | b64[rv] = '\0'; 156 | parseb64file(filename, b64, buf, buflen, comment); 157 | explicit_bzero(b64, sizeof(b64)); 158 | close(fd); 159 | } 160 | 161 | static uint8_t * 162 | readmsg(const char *filename, unsigned long long *msglenp) 163 | { 164 | unsigned long long msglen = 0; 165 | uint8_t *msg = NULL; 166 | struct stat sb; 167 | ssize_t x, space; 168 | int fd; 169 | const unsigned long long maxmsgsize = 1UL << 30; 170 | 171 | fd = xopen(filename, O_RDONLY | O_NOFOLLOW, 0); 172 | if (fstat(fd, &sb) == 0 && S_ISREG(sb.st_mode)) { 173 | if (sb.st_size > maxmsgsize) 174 | errx(1, "msg too large in %s", filename); 175 | space = sb.st_size + 1; 176 | } else { 177 | space = 64 * 1024 - 1; 178 | } 179 | 180 | msg = xmalloc(space + 1); 181 | while (1) { 182 | if (space == 0) { 183 | if (msglen * 2 > maxmsgsize) 184 | errx(1, "msg too large in %s", filename); 185 | space = msglen; 186 | if (!(msg = realloc(msg, msglen + space + 1))) 187 | errx(1, "realloc"); 188 | } 189 | if ((x = read(fd, msg + msglen, space)) == -1) 190 | err(1, "read from %s", filename); 191 | if (x == 0) 192 | break; 193 | space -= x; 194 | msglen += x; 195 | } 196 | 197 | msg[msglen] = '\0'; 198 | close(fd); 199 | 200 | *msglenp = msglen; 201 | return msg; 202 | } 203 | 204 | static void 205 | writeall(int fd, const void *buf, size_t buflen, const char *filename) 206 | { 207 | ssize_t x; 208 | 209 | while (buflen != 0) { 210 | if ((x = write(fd, buf, buflen)) == -1) 211 | err(1, "write to %s", filename); 212 | buflen -= x; 213 | buf = (char *)buf + x; 214 | } 215 | } 216 | 217 | #ifndef VERIFYONLY 218 | static void 219 | writeb64file(const char *filename, const char *comment, const void *buf, 220 | size_t buflen, const void *msg, size_t msglen, int oflags, mode_t mode) 221 | { 222 | char header[1024]; 223 | char b64[1024]; 224 | int fd, rv, nr; 225 | 226 | fd = xopen(filename, O_CREAT|oflags|O_NOFOLLOW|O_WRONLY, mode); 227 | if ((nr = snprintf(header, sizeof(header), "%s%s\n", 228 | COMMENTHDR, comment)) == -1 || nr >= sizeof(header)) 229 | errx(1, "comment too long"); 230 | writeall(fd, header, strlen(header), filename); 231 | if ((rv = b64_ntop(buf, buflen, b64, sizeof(b64))) == -1) 232 | errx(1, "base64 encode failed"); 233 | b64[rv++] = '\n'; 234 | writeall(fd, b64, rv, filename); 235 | explicit_bzero(b64, sizeof(b64)); 236 | if (msg) 237 | writeall(fd, msg, msglen, filename); 238 | close(fd); 239 | } 240 | 241 | static void 242 | kdf(uint8_t *salt, size_t saltlen, int rounds, int allowstdin, int confirm, 243 | uint8_t *key, size_t keylen) 244 | { 245 | char pass[1024]; 246 | int rppflags = RPP_ECHO_OFF; 247 | 248 | if (rounds == 0) { 249 | memset(key, 0, keylen); 250 | return; 251 | } 252 | 253 | if (allowstdin && !isatty(STDIN_FILENO)) 254 | rppflags |= RPP_STDIN; 255 | if (!readpassphrase("passphrase: ", pass, sizeof(pass), rppflags)) 256 | errx(1, "unable to read passphrase"); 257 | if (strlen(pass) == 0) 258 | errx(1, "please provide a password"); 259 | if (confirm && !(rppflags & RPP_STDIN)) { 260 | char pass2[1024]; 261 | if (!readpassphrase("confirm passphrase: ", pass2, 262 | sizeof(pass2), rppflags)) 263 | errx(1, "unable to read passphrase"); 264 | if (strcmp(pass, pass2) != 0) 265 | errx(1, "passwords don't match"); 266 | explicit_bzero(pass2, sizeof(pass2)); 267 | } 268 | if (bcrypt_pbkdf(pass, strlen(pass), salt, saltlen, key, 269 | keylen, rounds) == -1) 270 | errx(1, "bcrypt pbkdf"); 271 | explicit_bzero(pass, sizeof(pass)); 272 | } 273 | 274 | static void 275 | signmsg(uint8_t *seckey, uint8_t *msg, unsigned long long msglen, 276 | uint8_t *sig) 277 | { 278 | unsigned long long siglen; 279 | uint8_t *sigbuf; 280 | 281 | sigbuf = xmalloc(msglen + SIGBYTES); 282 | crypto_sign_ed25519(sigbuf, &siglen, msg, msglen, seckey); 283 | memcpy(sig, sigbuf, SIGBYTES); 284 | free(sigbuf); 285 | } 286 | 287 | static void 288 | generate(const char *pubkeyfile, const char *seckeyfile, int rounds, 289 | const char *comment) 290 | { 291 | uint8_t digest[SHA512_DIGEST_LENGTH]; 292 | struct pubkey pubkey; 293 | struct enckey enckey; 294 | uint8_t xorkey[sizeof(enckey.seckey)]; 295 | uint8_t keynum[KEYNUMLEN]; 296 | char commentbuf[COMMENTMAXLEN]; 297 | SHA2_CTX ctx; 298 | int i, nr; 299 | 300 | crypto_sign_ed25519_keypair(pubkey.pubkey, enckey.seckey); 301 | arc4random_buf(keynum, sizeof(keynum)); 302 | 303 | SHA512Init(&ctx); 304 | SHA512Update(&ctx, enckey.seckey, sizeof(enckey.seckey)); 305 | SHA512Final(digest, &ctx); 306 | 307 | memcpy(enckey.pkalg, PKALG, 2); 308 | memcpy(enckey.kdfalg, KDFALG, 2); 309 | enckey.kdfrounds = htonl(rounds); 310 | memcpy(enckey.keynum, keynum, KEYNUMLEN); 311 | arc4random_buf(enckey.salt, sizeof(enckey.salt)); 312 | kdf(enckey.salt, sizeof(enckey.salt), rounds, 1, 1, xorkey, sizeof(xorkey)); 313 | memcpy(enckey.checksum, digest, sizeof(enckey.checksum)); 314 | for (i = 0; i < sizeof(enckey.seckey); i++) 315 | enckey.seckey[i] ^= xorkey[i]; 316 | explicit_bzero(digest, sizeof(digest)); 317 | explicit_bzero(xorkey, sizeof(xorkey)); 318 | 319 | if ((nr = snprintf(commentbuf, sizeof(commentbuf), "%s secret key", 320 | comment)) == -1 || nr >= sizeof(commentbuf)) 321 | errx(1, "comment too long"); 322 | writeb64file(seckeyfile, commentbuf, &enckey, 323 | sizeof(enckey), NULL, 0, O_EXCL, 0600); 324 | explicit_bzero(&enckey, sizeof(enckey)); 325 | 326 | memcpy(pubkey.pkalg, PKALG, 2); 327 | memcpy(pubkey.keynum, keynum, KEYNUMLEN); 328 | if ((nr = snprintf(commentbuf, sizeof(commentbuf), "%s public key", 329 | comment)) == -1 || nr >= sizeof(commentbuf)) 330 | errx(1, "comment too long"); 331 | writeb64file(pubkeyfile, commentbuf, &pubkey, 332 | sizeof(pubkey), NULL, 0, O_EXCL, 0666); 333 | } 334 | 335 | static void 336 | sign(const char *seckeyfile, const char *msgfile, const char *sigfile, 337 | int embedded) 338 | { 339 | struct sig sig; 340 | uint8_t digest[SHA512_DIGEST_LENGTH]; 341 | struct enckey enckey; 342 | uint8_t xorkey[sizeof(enckey.seckey)]; 343 | uint8_t *msg; 344 | char comment[COMMENTMAXLEN], sigcomment[COMMENTMAXLEN]; 345 | char *secname; 346 | unsigned long long msglen; 347 | int i, rounds, nr; 348 | SHA2_CTX ctx; 349 | 350 | readb64file(seckeyfile, &enckey, sizeof(enckey), comment); 351 | 352 | if (memcmp(enckey.kdfalg, KDFALG, 2) != 0) 353 | errx(1, "unsupported KDF"); 354 | rounds = ntohl(enckey.kdfrounds); 355 | kdf(enckey.salt, sizeof(enckey.salt), rounds, strcmp(msgfile, "-") != 0, 356 | 0, xorkey, sizeof(xorkey)); 357 | for (i = 0; i < sizeof(enckey.seckey); i++) 358 | enckey.seckey[i] ^= xorkey[i]; 359 | explicit_bzero(xorkey, sizeof(xorkey)); 360 | SHA512Init(&ctx); 361 | SHA512Update(&ctx, enckey.seckey, sizeof(enckey.seckey)); 362 | SHA512Final(digest, &ctx); 363 | if (memcmp(enckey.checksum, digest, sizeof(enckey.checksum)) != 0) 364 | errx(1, "incorrect passphrase"); 365 | explicit_bzero(digest, sizeof(digest)); 366 | 367 | msg = readmsg(msgfile, &msglen); 368 | 369 | signmsg(enckey.seckey, msg, msglen, sig.sig); 370 | memcpy(sig.keynum, enckey.keynum, KEYNUMLEN); 371 | explicit_bzero(&enckey, sizeof(enckey)); 372 | 373 | memcpy(sig.pkalg, PKALG, 2); 374 | secname = strstr(seckeyfile, ".sec"); 375 | if (secname && strlen(secname) == 4) { 376 | if ((nr = snprintf(sigcomment, sizeof(sigcomment), VERIFYWITH "%.*s.pub", 377 | (int)strlen(seckeyfile) - 4, seckeyfile)) == -1 || nr >= sizeof(sigcomment)) 378 | errx(1, "comment too long"); 379 | } else { 380 | if ((nr = snprintf(sigcomment, sizeof(sigcomment), "signature from %s", 381 | comment)) == -1 || nr >= sizeof(sigcomment)) 382 | errx(1, "comment too long"); 383 | } 384 | if (embedded) 385 | writeb64file(sigfile, sigcomment, &sig, sizeof(sig), msg, 386 | msglen, O_TRUNC, 0666); 387 | else 388 | writeb64file(sigfile, sigcomment, &sig, sizeof(sig), NULL, 389 | 0, O_TRUNC, 0666); 390 | 391 | free(msg); 392 | } 393 | #endif 394 | 395 | static void 396 | verifymsg(struct pubkey *pubkey, uint8_t *msg, unsigned long long msglen, 397 | struct sig *sig, int quiet) 398 | { 399 | uint8_t *sigbuf, *dummybuf; 400 | unsigned long long siglen, dummylen; 401 | 402 | if (memcmp(pubkey->keynum, sig->keynum, KEYNUMLEN) != 0) 403 | errx(1, "verification failed: checked against wrong key"); 404 | 405 | siglen = SIGBYTES + msglen; 406 | sigbuf = xmalloc(siglen); 407 | dummybuf = xmalloc(siglen); 408 | memcpy(sigbuf, sig->sig, SIGBYTES); 409 | memcpy(sigbuf + SIGBYTES, msg, msglen); 410 | if (crypto_sign_ed25519_open(dummybuf, &dummylen, sigbuf, siglen, 411 | pubkey->pubkey) == -1) 412 | errx(1, "signature verification failed"); 413 | if (!quiet) 414 | printf("Signature Verified\n"); 415 | free(sigbuf); 416 | free(dummybuf); 417 | } 418 | 419 | static void 420 | readpubkey(const char *pubkeyfile, struct pubkey *pubkey, 421 | const char *sigcomment) 422 | { 423 | const char *safepath = "/etc/signify/"; 424 | 425 | if (!pubkeyfile) { 426 | pubkeyfile = strstr(sigcomment, VERIFYWITH); 427 | if (pubkeyfile) { 428 | pubkeyfile += strlen(VERIFYWITH); 429 | if (strncmp(pubkeyfile, safepath, strlen(safepath)) != 0 || 430 | strstr(pubkeyfile, "/../") != NULL) 431 | errx(1, "untrusted path %s", pubkeyfile); 432 | } else 433 | usage("must specify pubkey"); 434 | } 435 | readb64file(pubkeyfile, pubkey, sizeof(*pubkey), NULL); 436 | } 437 | 438 | static void 439 | verifysimple(const char *pubkeyfile, const char *msgfile, const char *sigfile, 440 | int quiet) 441 | { 442 | char sigcomment[COMMENTMAXLEN]; 443 | struct sig sig; 444 | struct pubkey pubkey; 445 | unsigned long long msglen; 446 | uint8_t *msg; 447 | 448 | msg = readmsg(msgfile, &msglen); 449 | 450 | readb64file(sigfile, &sig, sizeof(sig), sigcomment); 451 | readpubkey(pubkeyfile, &pubkey, sigcomment); 452 | 453 | verifymsg(&pubkey, msg, msglen, &sig, quiet); 454 | 455 | free(msg); 456 | } 457 | 458 | static uint8_t * 459 | verifyembedded(const char *pubkeyfile, const char *sigfile, 460 | int quiet, unsigned long long *msglenp) 461 | { 462 | char sigcomment[COMMENTMAXLEN]; 463 | struct sig sig; 464 | struct pubkey pubkey; 465 | unsigned long long msglen, siglen; 466 | uint8_t *msg; 467 | 468 | msg = readmsg(sigfile, &msglen); 469 | 470 | siglen = parseb64file(sigfile, msg, &sig, sizeof(sig), sigcomment); 471 | readpubkey(pubkeyfile, &pubkey, sigcomment); 472 | 473 | msglen -= siglen; 474 | memmove(msg, msg + siglen, msglen); 475 | msg[msglen] = 0; 476 | 477 | verifymsg(&pubkey, msg, msglen, &sig, quiet); 478 | 479 | *msglenp = msglen; 480 | return msg; 481 | } 482 | 483 | static void 484 | verify(const char *pubkeyfile, const char *msgfile, const char *sigfile, 485 | int embedded, int quiet) 486 | { 487 | unsigned long long msglen; 488 | uint8_t *msg; 489 | int fd; 490 | 491 | if (embedded) { 492 | msg = verifyembedded(pubkeyfile, sigfile, quiet, &msglen); 493 | fd = xopen(msgfile, O_CREAT|O_TRUNC|O_NOFOLLOW|O_WRONLY, 0666); 494 | writeall(fd, msg, msglen, msgfile); 495 | free(msg); 496 | close(fd); 497 | } else { 498 | verifysimple(pubkeyfile, msgfile, sigfile, quiet); 499 | } 500 | } 501 | 502 | #ifndef VERIFYONLY 503 | #define HASHBUFSIZE 224 504 | struct checksum { 505 | char file[PATH_MAX]; 506 | char hash[HASHBUFSIZE]; 507 | char algo[32]; 508 | }; 509 | 510 | static void * 511 | ecalloc(size_t s1, size_t s2, void *data) 512 | { 513 | void *p; 514 | 515 | if (!(p = calloc(s1, s2))) 516 | err(1, "calloc"); 517 | return p; 518 | } 519 | 520 | static void 521 | efree(void *p, void *data) 522 | { 523 | free(p); 524 | } 525 | 526 | static void 527 | recodehash(char *hash, size_t len) 528 | { 529 | uint8_t data[HASHBUFSIZE / 2]; 530 | int i, rv; 531 | 532 | if (strlen(hash) == len) 533 | return; 534 | if ((rv = b64_pton(hash, data, sizeof(data))) == -1) 535 | errx(1, "invalid base64 encoding"); 536 | for (i = 0; i < rv; i++) 537 | snprintf(hash + i * 2, HASHBUFSIZE - i * 2, "%2.2x", data[i]); 538 | } 539 | 540 | static int 541 | verifychecksum(struct checksum *c, int quiet) 542 | { 543 | char buf[HASHBUFSIZE]; 544 | 545 | if (strcmp(c->algo, "SHA256") == 0) { 546 | recodehash(c->hash, SHA256_DIGEST_STRING_LENGTH-1); 547 | if (!SHA256File(c->file, buf)) 548 | return 0; 549 | } else if (strcmp(c->algo, "SHA512") == 0) { 550 | recodehash(c->hash, SHA512_DIGEST_STRING_LENGTH-1); 551 | if (!SHA512File(c->file, buf)) 552 | return 0; 553 | } else { 554 | errx(1, "can't handle algorithm %s", c->algo); 555 | } 556 | if (strcmp(c->hash, buf) != 0) { 557 | return 0; 558 | } 559 | if (!quiet) 560 | printf("%s: OK\n", c->file); 561 | return 1; 562 | } 563 | 564 | static void 565 | verifychecksums(char *msg, int argc, char **argv, int quiet) 566 | { 567 | struct ohash_info info = { 0, NULL, ecalloc, efree, NULL }; 568 | struct ohash myh; 569 | struct checksum c; 570 | char *e, *line, *endline; 571 | int hasfailed = 0; 572 | int i, rv; 573 | unsigned int slot; 574 | 575 | ohash_init(&myh, 6, &info); 576 | if (argc) { 577 | for (i = 0; i < argc; i++) { 578 | slot = ohash_qlookup(&myh, argv[i]); 579 | e = ohash_find(&myh, slot); 580 | if (e == NULL) 581 | ohash_insert(&myh, slot, argv[i]); 582 | } 583 | } 584 | 585 | line = msg; 586 | while (line && *line) { 587 | if ((endline = strchr(line, '\n'))) 588 | *endline++ = '\0'; 589 | #if PATH_MAX < 1024 || HASHBUFSIZE < 224 590 | #error sizes are wrong 591 | #endif 592 | rv = sscanf(line, "%31s (%1023[^)]) = %223s", 593 | c.algo, c.file, c.hash); 594 | if (rv != 3) 595 | errx(1, "unable to parse checksum line %s", line); 596 | line = endline; 597 | if (argc) { 598 | slot = ohash_qlookup(&myh, c.file); 599 | e = ohash_find(&myh, slot); 600 | if (e != NULL) { 601 | if (verifychecksum(&c, quiet) != 0) 602 | ohash_remove(&myh, slot); 603 | } 604 | } else { 605 | if (verifychecksum(&c, quiet) == 0) { 606 | slot = ohash_qlookup(&myh, c.file); 607 | e = ohash_find(&myh, slot); 608 | if (e == NULL) { 609 | if (!(e = strdup(c.file))) 610 | err(1, "strdup"); 611 | ohash_insert(&myh, slot, e); 612 | } 613 | } 614 | } 615 | } 616 | 617 | for (e = ohash_first(&myh, &slot); e != NULL; e = ohash_next(&myh, &slot)) { 618 | fprintf(stderr, "%s: FAIL\n", e); 619 | hasfailed = 1; 620 | if (argc == 0) 621 | free(e); 622 | } 623 | ohash_delete(&myh); 624 | if (hasfailed) 625 | exit(1); 626 | } 627 | 628 | static void 629 | check(const char *pubkeyfile, const char *sigfile, int quiet, int argc, 630 | char **argv) 631 | { 632 | unsigned long long msglen; 633 | uint8_t *msg; 634 | 635 | msg = verifyembedded(pubkeyfile, sigfile, quiet, &msglen); 636 | verifychecksums((char *)msg, argc, argv, quiet); 637 | 638 | free(msg); 639 | } 640 | #endif 641 | 642 | int 643 | main(int argc, char **argv) 644 | { 645 | const char *pubkeyfile = NULL, *seckeyfile = NULL, *msgfile = NULL, 646 | *sigfile = NULL; 647 | char sigfilebuf[PATH_MAX]; 648 | const char *comment = "signify"; 649 | int ch, rounds; 650 | int embedded = 0; 651 | int quiet = 0; 652 | enum { 653 | NONE, 654 | CHECK, 655 | GENERATE, 656 | SIGN, 657 | VERIFY 658 | } verb = NONE; 659 | 660 | 661 | rounds = 42; 662 | 663 | while ((ch = getopt(argc, argv, "CGSVc:em:np:qs:x:")) != -1) { 664 | switch (ch) { 665 | #ifndef VERIFYONLY 666 | case 'C': 667 | if (verb) 668 | usage(NULL); 669 | verb = CHECK; 670 | break; 671 | case 'G': 672 | if (verb) 673 | usage(NULL); 674 | verb = GENERATE; 675 | break; 676 | case 'S': 677 | if (verb) 678 | usage(NULL); 679 | verb = SIGN; 680 | break; 681 | #endif 682 | case 'V': 683 | if (verb) 684 | usage(NULL); 685 | verb = VERIFY; 686 | break; 687 | case 'c': 688 | comment = optarg; 689 | break; 690 | case 'e': 691 | embedded = 1; 692 | break; 693 | case 'm': 694 | msgfile = optarg; 695 | break; 696 | case 'n': 697 | rounds = 0; 698 | break; 699 | case 'p': 700 | pubkeyfile = optarg; 701 | break; 702 | case 'q': 703 | quiet = 1; 704 | break; 705 | case 's': 706 | seckeyfile = optarg; 707 | break; 708 | case 'x': 709 | sigfile = optarg; 710 | break; 711 | default: 712 | usage(NULL); 713 | break; 714 | } 715 | } 716 | argc -= optind; 717 | argv += optind; 718 | 719 | #ifndef VERIFYONLY 720 | if (verb == CHECK) { 721 | if (!sigfile) 722 | usage("must specify sigfile"); 723 | check(pubkeyfile, sigfile, quiet, argc, argv); 724 | return 0; 725 | } 726 | #endif 727 | 728 | if (argc != 0) 729 | usage(NULL); 730 | 731 | if (!sigfile && msgfile) { 732 | int nr; 733 | if (strcmp(msgfile, "-") == 0) 734 | usage("must specify sigfile with - message"); 735 | if ((nr = snprintf(sigfilebuf, sizeof(sigfilebuf), "%s.sig", 736 | msgfile)) == -1 || nr >= sizeof(sigfilebuf)) 737 | errx(1, "path too long"); 738 | sigfile = sigfilebuf; 739 | } 740 | 741 | switch (verb) { 742 | #ifndef VERIFYONLY 743 | case GENERATE: 744 | if (!pubkeyfile || !seckeyfile) 745 | usage("must specify pubkey and seckey"); 746 | generate(pubkeyfile, seckeyfile, rounds, comment); 747 | break; 748 | case SIGN: 749 | if (!msgfile || !seckeyfile) 750 | usage("must specify message and seckey"); 751 | sign(seckeyfile, msgfile, sigfile, embedded); 752 | break; 753 | #endif 754 | case VERIFY: 755 | if (!msgfile) 756 | usage("must specify message"); 757 | verify(pubkeyfile, msgfile, sigfile, embedded, quiet); 758 | break; 759 | default: 760 | usage(NULL); 761 | break; 762 | } 763 | 764 | return 0; 765 | } 766 | -------------------------------------------------------------------------------- /patched-src/sha2.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD: sha2.c,v 1.23 2015/01/15 13:05:59 millert Exp $ */ 2 | 3 | /* 4 | * FILE: sha2.c 5 | * AUTHOR: Aaron D. Gifford 6 | * 7 | * Copyright (c) 2000-2001, Aaron D. Gifford 8 | * All rights reserved. 9 | * 10 | * Redistribution and use in source and binary forms, with or without 11 | * modification, are permitted provided that the following conditions 12 | * are met: 13 | * 1. Redistributions of source code must retain the above copyright 14 | * notice, this list of conditions and the following disclaimer. 15 | * 2. Redistributions in binary form must reproduce the above copyright 16 | * notice, this list of conditions and the following disclaimer in the 17 | * documentation and/or other materials provided with the distribution. 18 | * 3. Neither the name of the copyright holder nor the names of contributors 19 | * may be used to endorse or promote products derived from this software 20 | * without specific prior written permission. 21 | * 22 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND 23 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE 26 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 | * SUCH DAMAGE. 33 | * 34 | * $From: sha2.c,v 1.1 2001/11/08 00:01:51 adg Exp adg $ 35 | */ 36 | 37 | #include "mingw.h" 38 | 39 | #include 40 | 41 | #include 42 | #include 43 | 44 | /* 45 | * UNROLLED TRANSFORM LOOP NOTE: 46 | * You can define SHA2_UNROLL_TRANSFORM to use the unrolled transform 47 | * loop version for the hash transform rounds (defined using macros 48 | * later in this file). Either define on the command line, for example: 49 | * 50 | * cc -DSHA2_UNROLL_TRANSFORM -o sha2 sha2.c sha2prog.c 51 | * 52 | * or define below: 53 | * 54 | * #define SHA2_UNROLL_TRANSFORM 55 | * 56 | */ 57 | #ifndef SHA2_SMALL 58 | #if defined(__amd64__) || defined(__i386__) 59 | #define SHA2_UNROLL_TRANSFORM 60 | #endif 61 | #endif 62 | 63 | /*** SHA-224/256/384/512 Machine Architecture Definitions *****************/ 64 | /* 65 | * BYTE_ORDER NOTE: 66 | * 67 | * Please make sure that your system defines BYTE_ORDER. If your 68 | * architecture is little-endian, make sure it also defines 69 | * LITTLE_ENDIAN and that the two (BYTE_ORDER and LITTLE_ENDIAN) are 70 | * equivilent. 71 | * 72 | * If your system does not define the above, then you can do so by 73 | * hand like this: 74 | * 75 | * #define LITTLE_ENDIAN 1234 76 | * #define BIG_ENDIAN 4321 77 | * 78 | * And for little-endian machines, add: 79 | * 80 | * #define BYTE_ORDER LITTLE_ENDIAN 81 | * 82 | * Or for big-endian machines: 83 | * 84 | * #define BYTE_ORDER BIG_ENDIAN 85 | * 86 | * The FreeBSD machine this was written on defines BYTE_ORDER 87 | * appropriately by including (which in turn includes 88 | * where the appropriate definitions are actually 89 | * made). 90 | */ 91 | #if !defined(BYTE_ORDER) || (BYTE_ORDER != LITTLE_ENDIAN && BYTE_ORDER != BIG_ENDIAN) 92 | #error Define BYTE_ORDER to be equal to either LITTLE_ENDIAN or BIG_ENDIAN 93 | #endif 94 | 95 | 96 | /*** SHA-224/256/384/512 Various Length Definitions ***********************/ 97 | /* NOTE: Most of these are in sha2.h */ 98 | #define SHA224_SHORT_BLOCK_LENGTH (SHA224_BLOCK_LENGTH - 8) 99 | #define SHA256_SHORT_BLOCK_LENGTH (SHA256_BLOCK_LENGTH - 8) 100 | #define SHA384_SHORT_BLOCK_LENGTH (SHA384_BLOCK_LENGTH - 16) 101 | #define SHA512_SHORT_BLOCK_LENGTH (SHA512_BLOCK_LENGTH - 16) 102 | 103 | /*** ENDIAN SPECIFIC COPY MACROS **************************************/ 104 | #define BE_8_TO_32(dst, cp) do { \ 105 | (dst) = (u_int32_t)(cp)[3] | ((u_int32_t)(cp)[2] << 8) | \ 106 | ((u_int32_t)(cp)[1] << 16) | ((u_int32_t)(cp)[0] << 24); \ 107 | } while(0) 108 | 109 | #define BE_8_TO_64(dst, cp) do { \ 110 | (dst) = (u_int64_t)(cp)[7] | ((u_int64_t)(cp)[6] << 8) | \ 111 | ((u_int64_t)(cp)[5] << 16) | ((u_int64_t)(cp)[4] << 24) | \ 112 | ((u_int64_t)(cp)[3] << 32) | ((u_int64_t)(cp)[2] << 40) | \ 113 | ((u_int64_t)(cp)[1] << 48) | ((u_int64_t)(cp)[0] << 56); \ 114 | } while (0) 115 | 116 | #define BE_64_TO_8(cp, src) do { \ 117 | (cp)[0] = (src) >> 56; \ 118 | (cp)[1] = (src) >> 48; \ 119 | (cp)[2] = (src) >> 40; \ 120 | (cp)[3] = (src) >> 32; \ 121 | (cp)[4] = (src) >> 24; \ 122 | (cp)[5] = (src) >> 16; \ 123 | (cp)[6] = (src) >> 8; \ 124 | (cp)[7] = (src); \ 125 | } while (0) 126 | 127 | #define BE_32_TO_8(cp, src) do { \ 128 | (cp)[0] = (src) >> 24; \ 129 | (cp)[1] = (src) >> 16; \ 130 | (cp)[2] = (src) >> 8; \ 131 | (cp)[3] = (src); \ 132 | } while (0) 133 | 134 | /* 135 | * Macro for incrementally adding the unsigned 64-bit integer n to the 136 | * unsigned 128-bit integer (represented using a two-element array of 137 | * 64-bit words): 138 | */ 139 | #define ADDINC128(w,n) do { \ 140 | (w)[0] += (u_int64_t)(n); \ 141 | if ((w)[0] < (n)) { \ 142 | (w)[1]++; \ 143 | } \ 144 | } while (0) 145 | 146 | /*** THE SIX LOGICAL FUNCTIONS ****************************************/ 147 | /* 148 | * Bit shifting and rotation (used by the six SHA-XYZ logical functions: 149 | * 150 | * NOTE: The naming of R and S appears backwards here (R is a SHIFT and 151 | * S is a ROTATION) because the SHA-224/256/384/512 description document 152 | * (see http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf) uses this 153 | * same "backwards" definition. 154 | */ 155 | /* Shift-right (used in SHA-224, SHA-256, SHA-384, and SHA-512): */ 156 | #define R(b,x) ((x) >> (b)) 157 | /* 32-bit Rotate-right (used in SHA-224 and SHA-256): */ 158 | #define S32(b,x) (((x) >> (b)) | ((x) << (32 - (b)))) 159 | /* 64-bit Rotate-right (used in SHA-384 and SHA-512): */ 160 | #define S64(b,x) (((x) >> (b)) | ((x) << (64 - (b)))) 161 | 162 | /* Two of six logical functions used in SHA-224, SHA-256, SHA-384, and SHA-512: */ 163 | #define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z))) 164 | #define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) 165 | 166 | /* Four of six logical functions used in SHA-224 and SHA-256: */ 167 | #define Sigma0_256(x) (S32(2, (x)) ^ S32(13, (x)) ^ S32(22, (x))) 168 | #define Sigma1_256(x) (S32(6, (x)) ^ S32(11, (x)) ^ S32(25, (x))) 169 | #define sigma0_256(x) (S32(7, (x)) ^ S32(18, (x)) ^ R(3 , (x))) 170 | #define sigma1_256(x) (S32(17, (x)) ^ S32(19, (x)) ^ R(10, (x))) 171 | 172 | /* Four of six logical functions used in SHA-384 and SHA-512: */ 173 | #define Sigma0_512(x) (S64(28, (x)) ^ S64(34, (x)) ^ S64(39, (x))) 174 | #define Sigma1_512(x) (S64(14, (x)) ^ S64(18, (x)) ^ S64(41, (x))) 175 | #define sigma0_512(x) (S64( 1, (x)) ^ S64( 8, (x)) ^ R( 7, (x))) 176 | #define sigma1_512(x) (S64(19, (x)) ^ S64(61, (x)) ^ R( 6, (x))) 177 | 178 | 179 | /*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/ 180 | /* Hash constant words K for SHA-224 and SHA-256: */ 181 | static const u_int32_t K256[64] = { 182 | 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 183 | 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 184 | 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL, 185 | 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL, 186 | 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, 187 | 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 188 | 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 189 | 0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL, 190 | 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL, 191 | 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, 192 | 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 193 | 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 194 | 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL, 195 | 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL, 196 | 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, 197 | 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL 198 | }; 199 | 200 | /* Initial hash value H for SHA-224: */ 201 | static const u_int32_t sha224_initial_hash_value[8] = { 202 | 0xc1059ed8UL, 203 | 0x367cd507UL, 204 | 0x3070dd17UL, 205 | 0xf70e5939UL, 206 | 0xffc00b31UL, 207 | 0x68581511UL, 208 | 0x64f98fa7UL, 209 | 0xbefa4fa4UL 210 | }; 211 | 212 | /* Initial hash value H for SHA-256: */ 213 | static const u_int32_t sha256_initial_hash_value[8] = { 214 | 0x6a09e667UL, 215 | 0xbb67ae85UL, 216 | 0x3c6ef372UL, 217 | 0xa54ff53aUL, 218 | 0x510e527fUL, 219 | 0x9b05688cUL, 220 | 0x1f83d9abUL, 221 | 0x5be0cd19UL 222 | }; 223 | 224 | /* Hash constant words K for SHA-384 and SHA-512: */ 225 | static const u_int64_t K512[80] = { 226 | 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 227 | 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL, 228 | 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, 229 | 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 230 | 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, 231 | 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL, 232 | 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 233 | 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL, 234 | 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, 235 | 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, 236 | 0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, 237 | 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL, 238 | 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 239 | 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL, 240 | 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, 241 | 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 242 | 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, 243 | 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL, 244 | 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 245 | 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL, 246 | 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, 247 | 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 248 | 0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, 249 | 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL, 250 | 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 251 | 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL, 252 | 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, 253 | 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, 254 | 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, 255 | 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL, 256 | 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 257 | 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL, 258 | 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, 259 | 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 260 | 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, 261 | 0x113f9804bef90daeULL, 0x1b710b35131c471bULL, 262 | 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 263 | 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL, 264 | 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, 265 | 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL 266 | }; 267 | 268 | /* Initial hash value H for SHA-512 */ 269 | static const u_int64_t sha512_initial_hash_value[8] = { 270 | 0x6a09e667f3bcc908ULL, 271 | 0xbb67ae8584caa73bULL, 272 | 0x3c6ef372fe94f82bULL, 273 | 0xa54ff53a5f1d36f1ULL, 274 | 0x510e527fade682d1ULL, 275 | 0x9b05688c2b3e6c1fULL, 276 | 0x1f83d9abfb41bd6bULL, 277 | 0x5be0cd19137e2179ULL 278 | }; 279 | 280 | #if !defined(SHA2_SMALL) 281 | /* Initial hash value H for SHA-384 */ 282 | static const u_int64_t sha384_initial_hash_value[8] = { 283 | 0xcbbb9d5dc1059ed8ULL, 284 | 0x629a292a367cd507ULL, 285 | 0x9159015a3070dd17ULL, 286 | 0x152fecd8f70e5939ULL, 287 | 0x67332667ffc00b31ULL, 288 | 0x8eb44a8768581511ULL, 289 | 0xdb0c2e0d64f98fa7ULL, 290 | 0x47b5481dbefa4fa4ULL 291 | }; 292 | 293 | /*** SHA-224: *********************************************************/ 294 | void 295 | SHA224Init(SHA2_CTX *context) 296 | { 297 | memcpy(context->state.st32, sha224_initial_hash_value, 298 | sizeof(sha224_initial_hash_value)); 299 | memset(context->buffer, 0, sizeof(context->buffer)); 300 | context->bitcount[0] = 0; 301 | } 302 | 303 | __weak_alias(SHA224Transform, SHA256Transform); 304 | __weak_alias(SHA224Update, SHA256Update); 305 | __weak_alias(SHA224Pad, SHA256Pad); 306 | 307 | void 308 | SHA224Final(u_int8_t digest[SHA224_DIGEST_LENGTH], SHA2_CTX *context) 309 | { 310 | SHA224Pad(context); 311 | 312 | #if BYTE_ORDER == LITTLE_ENDIAN 313 | int i; 314 | 315 | /* Convert TO host byte order */ 316 | for (i = 0; i < 7; i++) 317 | BE_32_TO_8(digest + i * 4, context->state.st32[i]); 318 | #else 319 | memcpy(digest, context->state.st32, SHA224_DIGEST_LENGTH); 320 | #endif 321 | explicit_bzero(context, sizeof(*context)); 322 | } 323 | #endif /* !defined(SHA2_SMALL) */ 324 | 325 | /*** SHA-256: *********************************************************/ 326 | void 327 | SHA256Init(SHA2_CTX *context) 328 | { 329 | memcpy(context->state.st32, sha256_initial_hash_value, 330 | sizeof(sha256_initial_hash_value)); 331 | memset(context->buffer, 0, sizeof(context->buffer)); 332 | context->bitcount[0] = 0; 333 | } 334 | 335 | #ifdef SHA2_UNROLL_TRANSFORM 336 | 337 | /* Unrolled SHA-256 round macros: */ 338 | 339 | #define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) do { \ 340 | BE_8_TO_32(W256[j], data); \ 341 | data += 4; \ 342 | T1 = (h) + Sigma1_256((e)) + Ch((e), (f), (g)) + K256[j] + W256[j]; \ 343 | (d) += T1; \ 344 | (h) = T1 + Sigma0_256((a)) + Maj((a), (b), (c)); \ 345 | j++; \ 346 | } while(0) 347 | 348 | #define ROUND256(a,b,c,d,e,f,g,h) do { \ 349 | s0 = W256[(j+1)&0x0f]; \ 350 | s0 = sigma0_256(s0); \ 351 | s1 = W256[(j+14)&0x0f]; \ 352 | s1 = sigma1_256(s1); \ 353 | T1 = (h) + Sigma1_256((e)) + Ch((e), (f), (g)) + K256[j] + \ 354 | (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); \ 355 | (d) += T1; \ 356 | (h) = T1 + Sigma0_256((a)) + Maj((a), (b), (c)); \ 357 | j++; \ 358 | } while(0) 359 | 360 | void 361 | SHA256Transform(u_int32_t state[8], const u_int8_t data[SHA256_BLOCK_LENGTH]) 362 | { 363 | u_int32_t a, b, c, d, e, f, g, h, s0, s1; 364 | u_int32_t T1, W256[16]; 365 | int j; 366 | 367 | /* Initialize registers with the prev. intermediate value */ 368 | a = state[0]; 369 | b = state[1]; 370 | c = state[2]; 371 | d = state[3]; 372 | e = state[4]; 373 | f = state[5]; 374 | g = state[6]; 375 | h = state[7]; 376 | 377 | j = 0; 378 | do { 379 | /* Rounds 0 to 15 (unrolled): */ 380 | ROUND256_0_TO_15(a,b,c,d,e,f,g,h); 381 | ROUND256_0_TO_15(h,a,b,c,d,e,f,g); 382 | ROUND256_0_TO_15(g,h,a,b,c,d,e,f); 383 | ROUND256_0_TO_15(f,g,h,a,b,c,d,e); 384 | ROUND256_0_TO_15(e,f,g,h,a,b,c,d); 385 | ROUND256_0_TO_15(d,e,f,g,h,a,b,c); 386 | ROUND256_0_TO_15(c,d,e,f,g,h,a,b); 387 | ROUND256_0_TO_15(b,c,d,e,f,g,h,a); 388 | } while (j < 16); 389 | 390 | /* Now for the remaining rounds up to 63: */ 391 | do { 392 | ROUND256(a,b,c,d,e,f,g,h); 393 | ROUND256(h,a,b,c,d,e,f,g); 394 | ROUND256(g,h,a,b,c,d,e,f); 395 | ROUND256(f,g,h,a,b,c,d,e); 396 | ROUND256(e,f,g,h,a,b,c,d); 397 | ROUND256(d,e,f,g,h,a,b,c); 398 | ROUND256(c,d,e,f,g,h,a,b); 399 | ROUND256(b,c,d,e,f,g,h,a); 400 | } while (j < 64); 401 | 402 | /* Compute the current intermediate hash value */ 403 | state[0] += a; 404 | state[1] += b; 405 | state[2] += c; 406 | state[3] += d; 407 | state[4] += e; 408 | state[5] += f; 409 | state[6] += g; 410 | state[7] += h; 411 | 412 | /* Clean up */ 413 | a = b = c = d = e = f = g = h = T1 = 0; 414 | } 415 | 416 | #else /* SHA2_UNROLL_TRANSFORM */ 417 | 418 | void 419 | SHA256Transform(u_int32_t state[8], const u_int8_t data[SHA256_BLOCK_LENGTH]) 420 | { 421 | u_int32_t a, b, c, d, e, f, g, h, s0, s1; 422 | u_int32_t T1, T2, W256[16]; 423 | int j; 424 | 425 | /* Initialize registers with the prev. intermediate value */ 426 | a = state[0]; 427 | b = state[1]; 428 | c = state[2]; 429 | d = state[3]; 430 | e = state[4]; 431 | f = state[5]; 432 | g = state[6]; 433 | h = state[7]; 434 | 435 | j = 0; 436 | do { 437 | BE_8_TO_32(W256[j], data); 438 | data += 4; 439 | /* Apply the SHA-256 compression function to update a..h */ 440 | T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + W256[j]; 441 | T2 = Sigma0_256(a) + Maj(a, b, c); 442 | h = g; 443 | g = f; 444 | f = e; 445 | e = d + T1; 446 | d = c; 447 | c = b; 448 | b = a; 449 | a = T1 + T2; 450 | 451 | j++; 452 | } while (j < 16); 453 | 454 | do { 455 | /* Part of the message block expansion: */ 456 | s0 = W256[(j+1)&0x0f]; 457 | s0 = sigma0_256(s0); 458 | s1 = W256[(j+14)&0x0f]; 459 | s1 = sigma1_256(s1); 460 | 461 | /* Apply the SHA-256 compression function to update a..h */ 462 | T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + 463 | (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); 464 | T2 = Sigma0_256(a) + Maj(a, b, c); 465 | h = g; 466 | g = f; 467 | f = e; 468 | e = d + T1; 469 | d = c; 470 | c = b; 471 | b = a; 472 | a = T1 + T2; 473 | 474 | j++; 475 | } while (j < 64); 476 | 477 | /* Compute the current intermediate hash value */ 478 | state[0] += a; 479 | state[1] += b; 480 | state[2] += c; 481 | state[3] += d; 482 | state[4] += e; 483 | state[5] += f; 484 | state[6] += g; 485 | state[7] += h; 486 | 487 | /* Clean up */ 488 | a = b = c = d = e = f = g = h = T1 = T2 = 0; 489 | } 490 | 491 | #endif /* SHA2_UNROLL_TRANSFORM */ 492 | 493 | void 494 | SHA256Update(SHA2_CTX *context, const u_int8_t *data, size_t len) 495 | { 496 | size_t freespace, usedspace; 497 | 498 | /* Calling with no data is valid (we do nothing) */ 499 | if (len == 0) 500 | return; 501 | 502 | usedspace = (context->bitcount[0] >> 3) % SHA256_BLOCK_LENGTH; 503 | if (usedspace > 0) { 504 | /* Calculate how much free space is available in the buffer */ 505 | freespace = SHA256_BLOCK_LENGTH - usedspace; 506 | 507 | if (len >= freespace) { 508 | /* Fill the buffer completely and process it */ 509 | memcpy(&context->buffer[usedspace], data, freespace); 510 | context->bitcount[0] += freespace << 3; 511 | len -= freespace; 512 | data += freespace; 513 | SHA256Transform(context->state.st32, context->buffer); 514 | } else { 515 | /* The buffer is not yet full */ 516 | memcpy(&context->buffer[usedspace], data, len); 517 | context->bitcount[0] += len << 3; 518 | /* Clean up: */ 519 | usedspace = freespace = 0; 520 | return; 521 | } 522 | } 523 | while (len >= SHA256_BLOCK_LENGTH) { 524 | /* Process as many complete blocks as we can */ 525 | SHA256Transform(context->state.st32, data); 526 | context->bitcount[0] += SHA256_BLOCK_LENGTH << 3; 527 | len -= SHA256_BLOCK_LENGTH; 528 | data += SHA256_BLOCK_LENGTH; 529 | } 530 | if (len > 0) { 531 | /* There's left-overs, so save 'em */ 532 | memcpy(context->buffer, data, len); 533 | context->bitcount[0] += len << 3; 534 | } 535 | /* Clean up: */ 536 | usedspace = freespace = 0; 537 | } 538 | 539 | void 540 | SHA256Pad(SHA2_CTX *context) 541 | { 542 | unsigned int usedspace; 543 | 544 | usedspace = (context->bitcount[0] >> 3) % SHA256_BLOCK_LENGTH; 545 | if (usedspace > 0) { 546 | /* Begin padding with a 1 bit: */ 547 | context->buffer[usedspace++] = 0x80; 548 | 549 | if (usedspace <= SHA256_SHORT_BLOCK_LENGTH) { 550 | /* Set-up for the last transform: */ 551 | memset(&context->buffer[usedspace], 0, 552 | SHA256_SHORT_BLOCK_LENGTH - usedspace); 553 | } else { 554 | if (usedspace < SHA256_BLOCK_LENGTH) { 555 | memset(&context->buffer[usedspace], 0, 556 | SHA256_BLOCK_LENGTH - usedspace); 557 | } 558 | /* Do second-to-last transform: */ 559 | SHA256Transform(context->state.st32, context->buffer); 560 | 561 | /* Prepare for last transform: */ 562 | memset(context->buffer, 0, SHA256_SHORT_BLOCK_LENGTH); 563 | } 564 | } else { 565 | /* Set-up for the last transform: */ 566 | memset(context->buffer, 0, SHA256_SHORT_BLOCK_LENGTH); 567 | 568 | /* Begin padding with a 1 bit: */ 569 | *context->buffer = 0x80; 570 | } 571 | /* Store the length of input data (in bits) in big endian format: */ 572 | BE_64_TO_8(&context->buffer[SHA256_SHORT_BLOCK_LENGTH], 573 | context->bitcount[0]); 574 | 575 | /* Final transform: */ 576 | SHA256Transform(context->state.st32, context->buffer); 577 | 578 | /* Clean up: */ 579 | usedspace = 0; 580 | } 581 | 582 | void 583 | SHA256Final(u_int8_t digest[SHA256_DIGEST_LENGTH], SHA2_CTX *context) 584 | { 585 | SHA256Pad(context); 586 | 587 | #if BYTE_ORDER == LITTLE_ENDIAN 588 | int i; 589 | 590 | /* Convert TO host byte order */ 591 | for (i = 0; i < 8; i++) 592 | BE_32_TO_8(digest + i * 4, context->state.st32[i]); 593 | #else 594 | memcpy(digest, context->state.st32, SHA256_DIGEST_LENGTH); 595 | #endif 596 | explicit_bzero(context, sizeof(*context)); 597 | } 598 | 599 | 600 | /*** SHA-512: *********************************************************/ 601 | void 602 | SHA512Init(SHA2_CTX *context) 603 | { 604 | memcpy(context->state.st64, sha512_initial_hash_value, 605 | sizeof(sha512_initial_hash_value)); 606 | memset(context->buffer, 0, sizeof(context->buffer)); 607 | context->bitcount[0] = context->bitcount[1] = 0; 608 | } 609 | 610 | #ifdef SHA2_UNROLL_TRANSFORM 611 | 612 | /* Unrolled SHA-512 round macros: */ 613 | 614 | #define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) do { \ 615 | BE_8_TO_64(W512[j], data); \ 616 | data += 8; \ 617 | T1 = (h) + Sigma1_512((e)) + Ch((e), (f), (g)) + K512[j] + W512[j]; \ 618 | (d) += T1; \ 619 | (h) = T1 + Sigma0_512((a)) + Maj((a), (b), (c)); \ 620 | j++; \ 621 | } while(0) 622 | 623 | 624 | #define ROUND512(a,b,c,d,e,f,g,h) do { \ 625 | s0 = W512[(j+1)&0x0f]; \ 626 | s0 = sigma0_512(s0); \ 627 | s1 = W512[(j+14)&0x0f]; \ 628 | s1 = sigma1_512(s1); \ 629 | T1 = (h) + Sigma1_512((e)) + Ch((e), (f), (g)) + K512[j] + \ 630 | (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); \ 631 | (d) += T1; \ 632 | (h) = T1 + Sigma0_512((a)) + Maj((a), (b), (c)); \ 633 | j++; \ 634 | } while(0) 635 | 636 | void 637 | SHA512Transform(u_int64_t state[8], const u_int8_t data[SHA512_BLOCK_LENGTH]) 638 | { 639 | u_int64_t a, b, c, d, e, f, g, h, s0, s1; 640 | u_int64_t T1, W512[16]; 641 | int j; 642 | 643 | /* Initialize registers with the prev. intermediate value */ 644 | a = state[0]; 645 | b = state[1]; 646 | c = state[2]; 647 | d = state[3]; 648 | e = state[4]; 649 | f = state[5]; 650 | g = state[6]; 651 | h = state[7]; 652 | 653 | j = 0; 654 | do { 655 | /* Rounds 0 to 15 (unrolled): */ 656 | ROUND512_0_TO_15(a,b,c,d,e,f,g,h); 657 | ROUND512_0_TO_15(h,a,b,c,d,e,f,g); 658 | ROUND512_0_TO_15(g,h,a,b,c,d,e,f); 659 | ROUND512_0_TO_15(f,g,h,a,b,c,d,e); 660 | ROUND512_0_TO_15(e,f,g,h,a,b,c,d); 661 | ROUND512_0_TO_15(d,e,f,g,h,a,b,c); 662 | ROUND512_0_TO_15(c,d,e,f,g,h,a,b); 663 | ROUND512_0_TO_15(b,c,d,e,f,g,h,a); 664 | } while (j < 16); 665 | 666 | /* Now for the remaining rounds up to 79: */ 667 | do { 668 | ROUND512(a,b,c,d,e,f,g,h); 669 | ROUND512(h,a,b,c,d,e,f,g); 670 | ROUND512(g,h,a,b,c,d,e,f); 671 | ROUND512(f,g,h,a,b,c,d,e); 672 | ROUND512(e,f,g,h,a,b,c,d); 673 | ROUND512(d,e,f,g,h,a,b,c); 674 | ROUND512(c,d,e,f,g,h,a,b); 675 | ROUND512(b,c,d,e,f,g,h,a); 676 | } while (j < 80); 677 | 678 | /* Compute the current intermediate hash value */ 679 | state[0] += a; 680 | state[1] += b; 681 | state[2] += c; 682 | state[3] += d; 683 | state[4] += e; 684 | state[5] += f; 685 | state[6] += g; 686 | state[7] += h; 687 | 688 | /* Clean up */ 689 | a = b = c = d = e = f = g = h = T1 = 0; 690 | } 691 | 692 | #else /* SHA2_UNROLL_TRANSFORM */ 693 | 694 | void 695 | SHA512Transform(u_int64_t state[8], const u_int8_t data[SHA512_BLOCK_LENGTH]) 696 | { 697 | u_int64_t a, b, c, d, e, f, g, h, s0, s1; 698 | u_int64_t T1, T2, W512[16]; 699 | int j; 700 | 701 | /* Initialize registers with the prev. intermediate value */ 702 | a = state[0]; 703 | b = state[1]; 704 | c = state[2]; 705 | d = state[3]; 706 | e = state[4]; 707 | f = state[5]; 708 | g = state[6]; 709 | h = state[7]; 710 | 711 | j = 0; 712 | do { 713 | BE_8_TO_64(W512[j], data); 714 | data += 8; 715 | /* Apply the SHA-512 compression function to update a..h */ 716 | T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + W512[j]; 717 | T2 = Sigma0_512(a) + Maj(a, b, c); 718 | h = g; 719 | g = f; 720 | f = e; 721 | e = d + T1; 722 | d = c; 723 | c = b; 724 | b = a; 725 | a = T1 + T2; 726 | 727 | j++; 728 | } while (j < 16); 729 | 730 | do { 731 | /* Part of the message block expansion: */ 732 | s0 = W512[(j+1)&0x0f]; 733 | s0 = sigma0_512(s0); 734 | s1 = W512[(j+14)&0x0f]; 735 | s1 = sigma1_512(s1); 736 | 737 | /* Apply the SHA-512 compression function to update a..h */ 738 | T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + 739 | (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); 740 | T2 = Sigma0_512(a) + Maj(a, b, c); 741 | h = g; 742 | g = f; 743 | f = e; 744 | e = d + T1; 745 | d = c; 746 | c = b; 747 | b = a; 748 | a = T1 + T2; 749 | 750 | j++; 751 | } while (j < 80); 752 | 753 | /* Compute the current intermediate hash value */ 754 | state[0] += a; 755 | state[1] += b; 756 | state[2] += c; 757 | state[3] += d; 758 | state[4] += e; 759 | state[5] += f; 760 | state[6] += g; 761 | state[7] += h; 762 | 763 | /* Clean up */ 764 | a = b = c = d = e = f = g = h = T1 = T2 = 0; 765 | } 766 | 767 | #endif /* SHA2_UNROLL_TRANSFORM */ 768 | 769 | void 770 | SHA512Update(SHA2_CTX *context, const u_int8_t *data, size_t len) 771 | { 772 | size_t freespace, usedspace; 773 | 774 | /* Calling with no data is valid (we do nothing) */ 775 | if (len == 0) 776 | return; 777 | 778 | usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH; 779 | if (usedspace > 0) { 780 | /* Calculate how much free space is available in the buffer */ 781 | freespace = SHA512_BLOCK_LENGTH - usedspace; 782 | 783 | if (len >= freespace) { 784 | /* Fill the buffer completely and process it */ 785 | memcpy(&context->buffer[usedspace], data, freespace); 786 | ADDINC128(context->bitcount, freespace << 3); 787 | len -= freespace; 788 | data += freespace; 789 | SHA512Transform(context->state.st64, context->buffer); 790 | } else { 791 | /* The buffer is not yet full */ 792 | memcpy(&context->buffer[usedspace], data, len); 793 | ADDINC128(context->bitcount, len << 3); 794 | /* Clean up: */ 795 | usedspace = freespace = 0; 796 | return; 797 | } 798 | } 799 | while (len >= SHA512_BLOCK_LENGTH) { 800 | /* Process as many complete blocks as we can */ 801 | SHA512Transform(context->state.st64, data); 802 | ADDINC128(context->bitcount, SHA512_BLOCK_LENGTH << 3); 803 | len -= SHA512_BLOCK_LENGTH; 804 | data += SHA512_BLOCK_LENGTH; 805 | } 806 | if (len > 0) { 807 | /* There's left-overs, so save 'em */ 808 | memcpy(context->buffer, data, len); 809 | ADDINC128(context->bitcount, len << 3); 810 | } 811 | /* Clean up: */ 812 | usedspace = freespace = 0; 813 | } 814 | 815 | void 816 | SHA512Pad(SHA2_CTX *context) 817 | { 818 | unsigned int usedspace; 819 | 820 | usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH; 821 | if (usedspace > 0) { 822 | /* Begin padding with a 1 bit: */ 823 | context->buffer[usedspace++] = 0x80; 824 | 825 | if (usedspace <= SHA512_SHORT_BLOCK_LENGTH) { 826 | /* Set-up for the last transform: */ 827 | memset(&context->buffer[usedspace], 0, SHA512_SHORT_BLOCK_LENGTH - usedspace); 828 | } else { 829 | if (usedspace < SHA512_BLOCK_LENGTH) { 830 | memset(&context->buffer[usedspace], 0, SHA512_BLOCK_LENGTH - usedspace); 831 | } 832 | /* Do second-to-last transform: */ 833 | SHA512Transform(context->state.st64, context->buffer); 834 | 835 | /* And set-up for the last transform: */ 836 | memset(context->buffer, 0, SHA512_BLOCK_LENGTH - 2); 837 | } 838 | } else { 839 | /* Prepare for final transform: */ 840 | memset(context->buffer, 0, SHA512_SHORT_BLOCK_LENGTH); 841 | 842 | /* Begin padding with a 1 bit: */ 843 | *context->buffer = 0x80; 844 | } 845 | /* Store the length of input data (in bits) in big endian format: */ 846 | BE_64_TO_8(&context->buffer[SHA512_SHORT_BLOCK_LENGTH], 847 | context->bitcount[1]); 848 | BE_64_TO_8(&context->buffer[SHA512_SHORT_BLOCK_LENGTH + 8], 849 | context->bitcount[0]); 850 | 851 | /* Final transform: */ 852 | SHA512Transform(context->state.st64, context->buffer); 853 | 854 | /* Clean up: */ 855 | usedspace = 0; 856 | } 857 | 858 | void 859 | SHA512Final(u_int8_t digest[SHA512_DIGEST_LENGTH], SHA2_CTX *context) 860 | { 861 | SHA512Pad(context); 862 | 863 | #if BYTE_ORDER == LITTLE_ENDIAN 864 | int i; 865 | 866 | /* Convert TO host byte order */ 867 | for (i = 0; i < 8; i++) 868 | BE_64_TO_8(digest + i * 8, context->state.st64[i]); 869 | #else 870 | memcpy(digest, context->state.st64, SHA512_DIGEST_LENGTH); 871 | #endif 872 | explicit_bzero(context, sizeof(*context)); 873 | } 874 | 875 | #if !defined(SHA2_SMALL) 876 | 877 | /*** SHA-384: *********************************************************/ 878 | void 879 | SHA384Init(SHA2_CTX *context) 880 | { 881 | memcpy(context->state.st64, sha384_initial_hash_value, 882 | sizeof(sha384_initial_hash_value)); 883 | memset(context->buffer, 0, sizeof(context->buffer)); 884 | context->bitcount[0] = context->bitcount[1] = 0; 885 | } 886 | 887 | __weak_alias(SHA384Transform, SHA512Transform); 888 | __weak_alias(SHA384Update, SHA512Update); 889 | __weak_alias(SHA384Pad, SHA512Pad); 890 | 891 | void 892 | SHA384Final(u_int8_t digest[SHA384_DIGEST_LENGTH], SHA2_CTX *context) 893 | { 894 | SHA384Pad(context); 895 | 896 | #if BYTE_ORDER == LITTLE_ENDIAN 897 | int i; 898 | 899 | /* Convert TO host byte order */ 900 | for (i = 0; i < 6; i++) 901 | BE_64_TO_8(digest + i * 8, context->state.st64[i]); 902 | #else 903 | memcpy(digest, context->state.st64, SHA384_DIGEST_LENGTH); 904 | #endif 905 | /* Zero out state data */ 906 | explicit_bzero(context, sizeof(*context)); 907 | } 908 | #endif /* !defined(SHA2_SMALL) */ 909 | --------------------------------------------------------------------------------