mirror of
https://github.com/cryb-to/cryb-to.git
synced 2024-12-25 05:51:07 +00:00
initial code drop
This commit is contained in:
parent
2e28935df9
commit
ae99587ba4
93 changed files with 10601 additions and 0 deletions
14
Makefile.am
Normal file
14
Makefile.am
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
# $Id$
|
||||||
|
|
||||||
|
ACLOCAL_AMFLAGS = -I m4
|
||||||
|
|
||||||
|
SUBDIRS = include lib t
|
||||||
|
|
||||||
|
EXTRA_DIST = \
|
||||||
|
CREDITS \
|
||||||
|
HISTORY \
|
||||||
|
INSTALL \
|
||||||
|
LICENSE \
|
||||||
|
README \
|
||||||
|
RELNOTES \
|
||||||
|
autogen.sh
|
44
autogen.des
Executable file
44
autogen.des
Executable file
|
@ -0,0 +1,44 @@
|
||||||
|
#!/bin/sh
|
||||||
|
#
|
||||||
|
# $Id$
|
||||||
|
#
|
||||||
|
|
||||||
|
has() {
|
||||||
|
which "$@" >/dev/null 2>&1
|
||||||
|
}
|
||||||
|
|
||||||
|
# BullseyeCoverage needs to know exactly which compiler we're using
|
||||||
|
if has clang clang++ ; then
|
||||||
|
echo "using Clang"
|
||||||
|
export CC="${CC:-clang}"
|
||||||
|
export CPP="${CPP:-${CC} -E}"
|
||||||
|
export CXX="${CXX:-clang++}"
|
||||||
|
elif has gcc g++ ; then
|
||||||
|
echo "using GCC"
|
||||||
|
export CC="${CC:-gcc}"
|
||||||
|
export CPP="${CPP:-gcc -E}"
|
||||||
|
export CXX="${CXX:-g++}"
|
||||||
|
else
|
||||||
|
echo "WARNING: using default compiler," \
|
||||||
|
"coverage analysis may not work"
|
||||||
|
fi
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
if has cov01 ; then
|
||||||
|
cov01 -u
|
||||||
|
cov01 -0
|
||||||
|
fi
|
||||||
|
|
||||||
|
. ./autogen.sh
|
||||||
|
|
||||||
|
./configure \
|
||||||
|
--with-openssl \
|
||||||
|
--with-rsaref \
|
||||||
|
--enable-developer-warnings \
|
||||||
|
--enable-werror \
|
||||||
|
"$@"
|
||||||
|
|
||||||
|
if has cov01 ; then
|
||||||
|
cov01 -o
|
||||||
|
fi
|
10
autogen.sh
Executable file
10
autogen.sh
Executable file
|
@ -0,0 +1,10 @@
|
||||||
|
#!/bin/sh
|
||||||
|
#
|
||||||
|
# $Id$
|
||||||
|
#
|
||||||
|
|
||||||
|
libtoolize --copy --force
|
||||||
|
aclocal -I m4
|
||||||
|
autoheader
|
||||||
|
automake -a -c --foreign
|
||||||
|
autoconf
|
114
configure.ac
Normal file
114
configure.ac
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
AC_PREREQ([2.63])
|
||||||
|
AC_REVISION([$Id$])
|
||||||
|
AC_INIT([cryb.to], [trunk], [des@des.no], [crybto], [http://cryb.to/])
|
||||||
|
AC_CONFIG_SRCDIR([include/cryb/to.h])
|
||||||
|
AC_CONFIG_MACRO_DIR([m4])
|
||||||
|
AM_INIT_AUTOMAKE([foreign])
|
||||||
|
AM_CONFIG_HEADER([include/config.h])
|
||||||
|
|
||||||
|
# C compiler and features
|
||||||
|
AC_LANG(C)
|
||||||
|
AC_PROG_CC
|
||||||
|
AC_PROG_CC_STDC
|
||||||
|
AC_PROG_CPP
|
||||||
|
AC_C_CONST
|
||||||
|
AC_C_RESTRICT
|
||||||
|
AC_C_VOLATILE
|
||||||
|
AC_C_BIGENDIAN
|
||||||
|
|
||||||
|
# libtool
|
||||||
|
LT_PREREQ([2.2.6])
|
||||||
|
LT_INIT()
|
||||||
|
|
||||||
|
# other programs
|
||||||
|
AC_PROG_INSTALL
|
||||||
|
|
||||||
|
# Include benchmarks in unit tests
|
||||||
|
AC_ARG_WITH([benchmarks],
|
||||||
|
AC_HELP_STRING([--with-benchmarks],
|
||||||
|
[include benchmarks in unit tests]),
|
||||||
|
[],
|
||||||
|
[with_benchmarks=no])
|
||||||
|
AM_CONDITIONAL([WITH_BENCHMARKS], [test x"$with_benchmarks" = x"yes"])
|
||||||
|
|
||||||
|
# OpenSSL versions of the unit tests for comparison
|
||||||
|
AC_ARG_WITH([openssl],
|
||||||
|
AC_HELP_STRING([--with-openssl],
|
||||||
|
[build unit tests with OpenSSL support]),
|
||||||
|
[],
|
||||||
|
[with_openssl=no])
|
||||||
|
AM_CONDITIONAL([WITH_OPENSSL], [test x"$with_openssl" = x"yes"])
|
||||||
|
|
||||||
|
# RSAREF versions of the unit tests for comparison
|
||||||
|
AC_ARG_WITH([rsaref],
|
||||||
|
AC_HELP_STRING([--with-rsaref],
|
||||||
|
[build unit tests with RSAREF support]),
|
||||||
|
[],
|
||||||
|
[with_rsaref=no])
|
||||||
|
AM_CONDITIONAL([WITH_RSAREF], [test x"$with_rsaref" = x"yes"])
|
||||||
|
|
||||||
|
# Documentation
|
||||||
|
AC_ARG_WITH([doc],
|
||||||
|
AC_HELP_STRING([--without-doc],
|
||||||
|
[do not build the documentation]),
|
||||||
|
[],
|
||||||
|
[with_doc=yes])
|
||||||
|
AM_CONDITIONAL([WITH_DOC], [test x"$with_doc" = x"yes"])
|
||||||
|
|
||||||
|
# Message digests
|
||||||
|
AC_ARG_WITH([digest],
|
||||||
|
AC_HELP_STRING([--without-digest],
|
||||||
|
[do not build the message digest library and tools]),
|
||||||
|
[],
|
||||||
|
[with_digest=yes])
|
||||||
|
AM_CONDITIONAL([WITH_DIGEST], [test x"$with_digest" = x"yes"])
|
||||||
|
|
||||||
|
# Message authentication codes
|
||||||
|
AC_ARG_WITH([mac],
|
||||||
|
AC_HELP_STRING([--without-mac],
|
||||||
|
[do not build the message authentication code library and tools]),
|
||||||
|
[],
|
||||||
|
[with_mac=yes])
|
||||||
|
AM_CONDITIONAL([WITH_MAC], [test x"$with_digest" = x"yes"])
|
||||||
|
|
||||||
|
# OATH
|
||||||
|
AC_ARG_WITH([oath],
|
||||||
|
AC_HELP_STRING([--without-oath],
|
||||||
|
[do not build the OATH library and tools]),
|
||||||
|
[],
|
||||||
|
[with_oath=yes])
|
||||||
|
AM_CONDITIONAL([WITH_OATH], [test x"$with_oath" = x"yes"])
|
||||||
|
|
||||||
|
# Developer-friendly compiler flags
|
||||||
|
AC_ARG_ENABLE([developer-warnings],
|
||||||
|
AS_HELP_STRING([--enable-developer-warnings],
|
||||||
|
[enable strict warnings (default is NO)]),
|
||||||
|
[CFLAGS="${CFLAGS} -Wall -Wextra"])
|
||||||
|
AC_ARG_ENABLE([debugging-symbols],
|
||||||
|
AS_HELP_STRING([--enable-debugging-symbols],
|
||||||
|
[enable debugging symbols (default is NO)]),
|
||||||
|
[CFLAGS="${CFLAGS} -O0 -g -fno-inline"])
|
||||||
|
AC_ARG_ENABLE([werror],
|
||||||
|
AS_HELP_STRING([--enable-werror],
|
||||||
|
[use -Werror (default is NO)]),
|
||||||
|
[CFLAGS="${CFLAGS} -Werror"])
|
||||||
|
|
||||||
|
AC_CHECK_HEADERS([endian.h sys/endian.h])
|
||||||
|
|
||||||
|
AC_CHECK_FUNCS([strlcat strlcmp strlcpy])
|
||||||
|
|
||||||
|
AC_CONFIG_FILES([
|
||||||
|
Makefile
|
||||||
|
include/Makefile
|
||||||
|
include/cryb/Makefile
|
||||||
|
lib/Makefile
|
||||||
|
lib/core/Makefile
|
||||||
|
lib/digest/Makefile
|
||||||
|
lib/enc/Makefile
|
||||||
|
lib/mac/Makefile
|
||||||
|
lib/oath/Makefile
|
||||||
|
lib/rand/Makefile
|
||||||
|
lib/rsaref/Makefile
|
||||||
|
t/Makefile
|
||||||
|
])
|
||||||
|
AC_OUTPUT
|
3
include/Makefile.am
Normal file
3
include/Makefile.am
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
# $Id$
|
||||||
|
|
||||||
|
SUBDIRS = cryb
|
28
include/cryb/Makefile.am
Normal file
28
include/cryb/Makefile.am
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
# $Id$
|
||||||
|
|
||||||
|
crybdir = $(includedir)/cryb
|
||||||
|
|
||||||
|
cryb_HEADERS = \
|
||||||
|
algorithm.h \
|
||||||
|
attributes.h \
|
||||||
|
bitwise.h \
|
||||||
|
digest.h \
|
||||||
|
hmac.h \
|
||||||
|
hotp.h \
|
||||||
|
mac.h \
|
||||||
|
md5.h \
|
||||||
|
oath.h \
|
||||||
|
oath_constants.h \
|
||||||
|
oath_types.h \
|
||||||
|
rand.h \
|
||||||
|
rfc3986.h \
|
||||||
|
rfc4648.h \
|
||||||
|
sha1.h \
|
||||||
|
to.h \
|
||||||
|
totp.h \
|
||||||
|
version.h
|
||||||
|
|
||||||
|
noinst_HEADERS = \
|
||||||
|
coverage.h \
|
||||||
|
impl.h \
|
||||||
|
nocoverage.h
|
49
include/cryb/algorithm.h
Normal file
49
include/cryb/algorithm.h
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2012 Universitetet i Oslo
|
||||||
|
* Copyright (c) 2012 Dag-Erling Smørgrav
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote
|
||||||
|
* products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Dag-Erling Smørgrav <des@des.no>
|
||||||
|
* Sponsor: the University of Oslo
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CRYB_ALGORITHM_H_INCLUDED
|
||||||
|
#define CRYB_ALGORITHM_H_INCLUDED
|
||||||
|
|
||||||
|
typedef enum algorithm_type {
|
||||||
|
digest_algorithm,
|
||||||
|
mac_algorithm,
|
||||||
|
} algorithm_type;
|
||||||
|
|
||||||
|
typedef struct algorithm {
|
||||||
|
algorithm_type type;
|
||||||
|
const char *name;
|
||||||
|
} algorithm;
|
||||||
|
|
||||||
|
#endif
|
49
include/cryb/attributes.h
Normal file
49
include/cryb/attributes.h
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2014 Dag-Erling Smørgrav
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote
|
||||||
|
* products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Dag-Erling Smørgrav <des@des.no>
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CRYB_ATTRIBUTES_H_INCLUDED
|
||||||
|
#define CRYB_ATTRIBUTES_H_INCLUDED
|
||||||
|
|
||||||
|
#if defined(__GNUC__) || defined(__clang__)
|
||||||
|
# define CRYB_PRINTF(fmt, arg) __attribute__((format(printf, fmt, arg)))
|
||||||
|
# define CRYB_NORETURN __attribute__((noreturn))
|
||||||
|
# define CRYB_UNUSED __attribute__((unused))
|
||||||
|
# define CRYB_USED __attribute__((used))
|
||||||
|
#else
|
||||||
|
# define CRYB_PRINTF(fmt, arg)
|
||||||
|
# define CRYB_NORETURN
|
||||||
|
# define CRYB_UNUSED
|
||||||
|
# define CRYB_USED
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
53
include/cryb/bitwise.h
Normal file
53
include/cryb/bitwise.h
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2012 Universitetet i Oslo
|
||||||
|
* Copyright (c) 2012 Dag-Erling Smørgrav
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote
|
||||||
|
* products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Dag-Erling Smørgrav <des@des.no>
|
||||||
|
* Sponsor: the University of Oslo
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CRYB_BITWISE_H_INCLUDED
|
||||||
|
#define CRYB_BITWISE_H_INCLUDED
|
||||||
|
|
||||||
|
static inline uint32_t
|
||||||
|
rol(uint32_t i, int n)
|
||||||
|
{
|
||||||
|
|
||||||
|
return (i << n | i >> (32 - n));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t
|
||||||
|
ror(uint32_t i, int n)
|
||||||
|
{
|
||||||
|
|
||||||
|
return (i << (32 - n) | i >> n);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
54
include/cryb/coverage.h
Normal file
54
include/cryb/coverage.h
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2014 Dag-Erling Smørgrav
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote
|
||||||
|
* products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Dag-Erling Smørgrav <des@des.no>
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CRYB_COVERAGE_H_INCLUDED
|
||||||
|
#define CRYB_COVERAGE_H_INCLUDED
|
||||||
|
|
||||||
|
#if _BullseyeCoverage
|
||||||
|
# define CRYB_DISABLE_COVERAGE _Pragma("BullseyeCoverage save off")
|
||||||
|
# define CRYB_RESTORE_COVERAGE _Pragma("BullseyeCoverage restore")
|
||||||
|
#else
|
||||||
|
# define CRYB_DISABLE_COVERAGE
|
||||||
|
# define CRYB_RESTORE_COVERAGE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Use at end of switch which has no default case
|
||||||
|
*/
|
||||||
|
#define CRYB_NO_DEFAULT_CASE \
|
||||||
|
CRYB_DISABLE_COVERAGE \
|
||||||
|
default: \
|
||||||
|
(void)0; \
|
||||||
|
CRYB_RESTORE_COVERAGE
|
||||||
|
|
||||||
|
#endif
|
107
include/cryb/ctype.h
Normal file
107
include/cryb/ctype.h
Normal file
|
@ -0,0 +1,107 @@
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2014 Dag-Erling Smørgrav
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote
|
||||||
|
* products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Dag-Erling Smørgrav <des@des.no>
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CRYB_CTYPE_H_INCLUDED
|
||||||
|
#define CRYB_CTYPE_H_INCLUDED
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Evaluates to non-zero if the argument is a digit.
|
||||||
|
*/
|
||||||
|
#define is_digit(ch) \
|
||||||
|
(ch >= '0' && ch <= '9')
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Evaluates to non-zero if the argument is a hex digit.
|
||||||
|
*/
|
||||||
|
#define is_xdigit(ch) \
|
||||||
|
((ch >= '0' && ch <= '9') || \
|
||||||
|
(ch >= 'a' && ch <= 'f') || \
|
||||||
|
(ch >= 'A' && ch <= 'F'))
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Evaluates to non-zero if the argument is an uppercase letter.
|
||||||
|
*/
|
||||||
|
#define is_upper(ch) \
|
||||||
|
(ch >= 'A' && ch <= 'Z')
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Evaluates to non-zero if the argument is a lowercase letter.
|
||||||
|
*/
|
||||||
|
#define is_lower(ch) \
|
||||||
|
(ch >= 'a' && ch <= 'z')
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Evaluates to non-zero if the argument is a letter.
|
||||||
|
*/
|
||||||
|
#define is_letter(ch) \
|
||||||
|
(is_upper(ch) || is_lower(ch))
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Evaluates to non-zero if the argument is a linear whitespace character.
|
||||||
|
* For the purposes of this macro, the definition of linear whitespace is
|
||||||
|
* extended to include the form feed and carraige return characters.
|
||||||
|
*/
|
||||||
|
#define is_lws(ch) \
|
||||||
|
(ch == ' ' || ch == '\t' || ch == '\f' || ch == '\r')
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Evaluates to non-zero if the argument is a whitespace character.
|
||||||
|
*/
|
||||||
|
#define is_ws(ch) \
|
||||||
|
(is_lws(ch) || ch == '\n')
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Evaluates to non-zero if the argument is a printable ASCII character.
|
||||||
|
* Assumes that the execution character set is a superset of ASCII.
|
||||||
|
*/
|
||||||
|
#define is_p(ch) \
|
||||||
|
(ch >= '!' && ch <= '~')
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Evaluates to non-zero if the argument belongs to the POSIX Portable
|
||||||
|
* Filename Character Set. Assumes that the execution character set is a
|
||||||
|
* superset of ASCII.
|
||||||
|
*/
|
||||||
|
#define is_pfcs(ch) \
|
||||||
|
(is_digit(ch) || is_letter(ch) || \
|
||||||
|
ch == '.' || ch == '_' || ch == '-')
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Evaluates to non-zero if the argument is an unreserved character
|
||||||
|
* according to RFC 3986, i.e. can be used unencoded in URIs.
|
||||||
|
*/
|
||||||
|
#define is_uri(ch) \
|
||||||
|
(is_digit(ch) || is_letter(ch) || \
|
||||||
|
ch == '.' || ch == '_' || ch == '-' || ch == '~')
|
||||||
|
|
||||||
|
#endif
|
85
include/cryb/digest.h
Normal file
85
include/cryb/digest.h
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2012 Universitetet i Oslo
|
||||||
|
* Copyright (c) 2012 Dag-Erling Smørgrav
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote
|
||||||
|
* products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Dag-Erling Smørgrav <des@des.no>
|
||||||
|
* Sponsor: the University of Oslo
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CRYB_DIGEST_H_INCLUDED
|
||||||
|
#define CRYB_DIGEST_H_INCLUDED
|
||||||
|
|
||||||
|
typedef void *(*digest_init_func)(void);
|
||||||
|
typedef void (*digest_update_func)(void *, const void *, size_t);
|
||||||
|
typedef void (*digest_final_func)(void *, void *);
|
||||||
|
typedef int (*digest_complete_func)(const void *, size_t, void *);
|
||||||
|
|
||||||
|
struct digest_algorithm {
|
||||||
|
const char *name; /* algorithm name */
|
||||||
|
size_t ctxsize; /* size of context structure */
|
||||||
|
size_t resultlen; /* length of the result */
|
||||||
|
digest_init_func init;
|
||||||
|
digest_update_func update;
|
||||||
|
digest_final_func final;
|
||||||
|
digest_complete_func complete;
|
||||||
|
};
|
||||||
|
|
||||||
|
const struct digest_algorithm *cryb_digest_algorithm(const char *);
|
||||||
|
|
||||||
|
void *cryb_digest_init(const char *);
|
||||||
|
void cryb_digest_update(void *, const void *, size_t);
|
||||||
|
void cryb_digest_final(void *, void *);
|
||||||
|
int cryb_digest_complete(const char *, const void *, size_t, void *);
|
||||||
|
|
||||||
|
static inline void *
|
||||||
|
digest_init(const char *alg)
|
||||||
|
{
|
||||||
|
return (cryb_digest_init(alg));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
digest_update(void *ctx, const void *msg, size_t msglen)
|
||||||
|
{
|
||||||
|
cryb_digest_update(ctx, msg, msglen);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
digest_final(void *ctx, void *md)
|
||||||
|
{
|
||||||
|
cryb_digest_final(ctx, md);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
digest_complete(const char *alg, const void *msg, size_t msglen, void *md)
|
||||||
|
{
|
||||||
|
return (cryb_digest_complete(alg, msg, msglen, md));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
53
include/cryb/hmac.h
Normal file
53
include/cryb/hmac.h
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2012 Universitetet i Oslo
|
||||||
|
* Copyright (c) 2012 Dag-Erling Smørgrav
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote
|
||||||
|
* products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Dag-Erling Smørgrav <des@des.no>
|
||||||
|
* Sponsor: the University of Oslo
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CRYB_HMAC_H_INCLUDED
|
||||||
|
#define CRYB_HMAC_H_INCLUDED
|
||||||
|
|
||||||
|
#define HMAC_LEN 20
|
||||||
|
|
||||||
|
typedef struct hmac_ctx {
|
||||||
|
struct sha1_ctx sha1_ctx;
|
||||||
|
uint8_t key[64];
|
||||||
|
size_t keylen;
|
||||||
|
} hmac_ctx;
|
||||||
|
|
||||||
|
|
||||||
|
void hmac_init(hmac_ctx *, const uint8_t *, size_t);
|
||||||
|
void hmac_update(hmac_ctx *, const uint8_t *, size_t);
|
||||||
|
void hmac_final(hmac_ctx *, uint8_t *);
|
||||||
|
void hmac_complete(const uint8_t *, size_t, const uint8_t *, size_t, uint8_t *);
|
||||||
|
|
||||||
|
#endif
|
39
include/cryb/hotp.h
Normal file
39
include/cryb/hotp.h
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2012 Universitetet i Oslo
|
||||||
|
* Copyright (c) 2012 Dag-Erling Smørgrav
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote
|
||||||
|
* products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Dag-Erling Smørgrav <des@des.no>
|
||||||
|
* Sponsor: the University of Oslo
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CRYB_HOTP_H_INCLUDED
|
||||||
|
#define CRYB_HOTP_H_INCLUDED
|
||||||
|
|
||||||
|
#endif
|
44
include/cryb/impl.h
Normal file
44
include/cryb/impl.h
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2014 Dag-Erling Smørgrav
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote
|
||||||
|
* products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Dag-Erling Smørgrav <des@des.no>
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CRYB_IMPL_H_INCLUDED
|
||||||
|
#define CRYB_IMPL_H_INCLUDED
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "cryb/attributes.h"
|
||||||
|
#include "cryb/coverage.h"
|
||||||
|
|
||||||
|
#endif
|
39
include/cryb/mac.h
Normal file
39
include/cryb/mac.h
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2012 Universitetet i Oslo
|
||||||
|
* Copyright (c) 2012 Dag-Erling Smørgrav
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote
|
||||||
|
* products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Dag-Erling Smørgrav <des@des.no>
|
||||||
|
* Sponsor: the University of Oslo
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CRYB_MAC_H_INCLUDED
|
||||||
|
#define CRYB_MAC_H_INCLUDED
|
||||||
|
|
||||||
|
#endif
|
57
include/cryb/md5.h
Normal file
57
include/cryb/md5.h
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2012 Universitetet i Oslo
|
||||||
|
* Copyright (c) 2012 Dag-Erling Smørgrav
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote
|
||||||
|
* products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Dag-Erling Smørgrav <des@des.no>
|
||||||
|
* Sponsor: the University of Oslo
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CRYB_MD5_H_INCLUDED
|
||||||
|
#define CRYB_MD5_H_INCLUDED
|
||||||
|
|
||||||
|
#define MD5_DIGEST_LEN 16
|
||||||
|
|
||||||
|
typedef struct md5_ctx {
|
||||||
|
uint8_t block[64];
|
||||||
|
size_t blocklen;
|
||||||
|
uint64_t bitlen;
|
||||||
|
uint32_t h[4];
|
||||||
|
} md5_ctx;
|
||||||
|
|
||||||
|
#define md5_init cryb_md5_init
|
||||||
|
#define md5_update cryb_md5_update
|
||||||
|
#define md5_final cryb_md5_final
|
||||||
|
#define md5_complete cryb_md5_complete
|
||||||
|
void md5_init(md5_ctx *);
|
||||||
|
void md5_update(md5_ctx *, const void *, size_t);
|
||||||
|
void md5_final(md5_ctx *, void *);
|
||||||
|
void md5_complete(const void *, size_t, void *);
|
||||||
|
|
||||||
|
#endif
|
60
include/cryb/oath.h
Normal file
60
include/cryb/oath.h
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2012-2014 Universitetet i Oslo
|
||||||
|
* Copyright (c) 2013-2014 Dag-Erling Smørgrav
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote
|
||||||
|
* products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Dag-Erling Smørgrav <des@des.no>
|
||||||
|
* Sponsor: the University of Oslo
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef OATH_H_INCLUDED
|
||||||
|
#define OATH_H_INCLUDED
|
||||||
|
|
||||||
|
#include <cryb/oath_constants.h>
|
||||||
|
#include <cryb/oath_types.h>
|
||||||
|
|
||||||
|
struct oath_key *oath_key_alloc(void);
|
||||||
|
struct oath_key *oath_key_create(const char *, enum oath_mode,
|
||||||
|
enum oath_hash, const char *, size_t);
|
||||||
|
void oath_key_free(struct oath_key *);
|
||||||
|
struct oath_key *oath_key_from_uri(const char *);
|
||||||
|
struct oath_key *oath_key_from_file(const char *);
|
||||||
|
char *oath_key_to_uri(const struct oath_key *);
|
||||||
|
|
||||||
|
struct oath_key *oath_key_dummy(enum oath_mode, enum oath_hash, unsigned int);
|
||||||
|
|
||||||
|
unsigned int oath_hotp(const uint8_t *, size_t, uint64_t, unsigned int);
|
||||||
|
unsigned int oath_hotp_current(struct oath_key *);
|
||||||
|
int oath_hotp_match(struct oath_key *, unsigned int, int);
|
||||||
|
|
||||||
|
unsigned int oath_totp(const uint8_t *, size_t, unsigned int);
|
||||||
|
unsigned int oath_totp_current(const struct oath_key *);
|
||||||
|
int oath_totp_match(struct oath_key *, unsigned int, int);
|
||||||
|
|
||||||
|
#endif
|
88
include/cryb/oath_constants.h
Normal file
88
include/cryb/oath_constants.h
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2012-2013 Universitetet i Oslo
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote
|
||||||
|
* products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Dag-Erling Smørgrav <des@des.no>
|
||||||
|
* Sponsor: the University of Oslo
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef OATH_CONSTANTS_H_INCLUDED
|
||||||
|
#define OATH_CONSTANTS_H_INCLUDED
|
||||||
|
|
||||||
|
/*
|
||||||
|
* OATH modes
|
||||||
|
*/
|
||||||
|
enum oath_mode {
|
||||||
|
om_undef, /* not set / default */
|
||||||
|
om_hotp, /* RFC 4226 HOTP */
|
||||||
|
om_totp, /* RFC 6238 TOTP */
|
||||||
|
om_ocra, /* RFC 6287 OCRA */
|
||||||
|
om_max
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Hash functions
|
||||||
|
*/
|
||||||
|
enum oath_hash {
|
||||||
|
oh_undef, /* not set / default */
|
||||||
|
oh_md5, /* RFC 1321 MD5 */
|
||||||
|
oh_sha1, /* FIPS 180 SHA-1 */
|
||||||
|
oh_sha256, /* FIPS 180 SHA-256 */
|
||||||
|
oh_sha512, /* FIPS 180 SHA-512 */
|
||||||
|
oh_max
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Default time step for TOTP: 30 seconds.
|
||||||
|
*/
|
||||||
|
#define OATH_DEF_TIMESTEP 30
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Maximum time step for TOTP: 10 minutes, which RFC 6238 cites as an
|
||||||
|
* example of an unreasonably large time step.
|
||||||
|
*/
|
||||||
|
#define OATH_MAX_TIMESTEP 600
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Maximum key length in bytes. HMAC has a 64-byte block size; if the key
|
||||||
|
* K is longer than that, HMAC derives a new key K' = H(K).
|
||||||
|
*/
|
||||||
|
#define OATH_MAX_KEYLEN 64
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Maximum label length in characters, including terminating NUL.
|
||||||
|
*/
|
||||||
|
#define OATH_MAX_LABELLEN 64
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Label to use for dummy keys
|
||||||
|
*/
|
||||||
|
#define OATH_DUMMY_LABEL "oath-dummy@openpam.org"
|
||||||
|
|
||||||
|
#endif
|
66
include/cryb/oath_types.h
Normal file
66
include/cryb/oath_types.h
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2012-2013 Universitetet i Oslo
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote
|
||||||
|
* products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Dag-Erling Smørgrav <des@des.no>
|
||||||
|
* Sponsor: the University of Oslo
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef OATH_TYPES_H_INCLUDED
|
||||||
|
#define OATH_TYPES_H_INCLUDED
|
||||||
|
|
||||||
|
/*
|
||||||
|
* OATH key and associated parameters
|
||||||
|
*/
|
||||||
|
struct oath_key {
|
||||||
|
/* mode and parameters */
|
||||||
|
enum oath_mode mode;
|
||||||
|
unsigned int digits;
|
||||||
|
uint64_t counter; /* HOTP only */
|
||||||
|
unsigned int timestep; /* TOTP only - in seconds */
|
||||||
|
uint64_t lastused; /* TOTP only */
|
||||||
|
|
||||||
|
/* housekeeping */
|
||||||
|
unsigned int dummy:1; /* dummy key, always fail */
|
||||||
|
unsigned int mapped:1; /* allocated with mmap() */
|
||||||
|
unsigned int locked:1; /* locked / wired with madvise() */
|
||||||
|
|
||||||
|
/* hash algorithm */
|
||||||
|
enum oath_hash hash;
|
||||||
|
|
||||||
|
/* label */
|
||||||
|
size_t labellen; /* bytes incl. NUL */
|
||||||
|
char label[OATH_MAX_LABELLEN];
|
||||||
|
|
||||||
|
/* key */
|
||||||
|
size_t keylen; /* bytes */
|
||||||
|
uint8_t key[OATH_MAX_KEYLEN];
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
40
include/cryb/rand.h
Normal file
40
include/cryb/rand.h
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2014 Dag-Erling Smørgrav
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote
|
||||||
|
* products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Dag-Erling Smørgrav <des@des.no>
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CRYB_RAND_H_INCLUDED
|
||||||
|
#define CRYB_RAND_H_INCLUDED
|
||||||
|
|
||||||
|
#define rand_bytes cryb_rand_bytes
|
||||||
|
int rand_bytes(uint8_t *, size_t);
|
||||||
|
|
||||||
|
#endif
|
46
include/cryb/rfc3986.h
Normal file
46
include/cryb/rfc3986.h
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2014 Dag-Erling Smørgrav
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote
|
||||||
|
* products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Dag-Erling Smørgrav <des@des.no>
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CRYB_RFC3986_H_INCLUDED
|
||||||
|
#define CRYB_RFC3986_H_INCLUDED
|
||||||
|
|
||||||
|
/* estimate of output length for percent encoding / decoding */
|
||||||
|
#define percent_enclen(l) (size_t)((l) * 3)
|
||||||
|
#define percent_declen(l) (size_t)(l)
|
||||||
|
|
||||||
|
#define percent_encode cryb_percent_encode
|
||||||
|
#define percent_decode cryb_percent_decode
|
||||||
|
int percent_encode(const char *, size_t, char *, size_t *);
|
||||||
|
int percent_decode(const char *, size_t, char *, size_t *);
|
||||||
|
|
||||||
|
#endif
|
58
include/cryb/rfc4648.h
Normal file
58
include/cryb/rfc4648.h
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2012-2013 Universitetet i Oslo
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote
|
||||||
|
* products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Dag-Erling Smørgrav <des@des.no>
|
||||||
|
* Sponsor: the University of Oslo
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CRYB_RFC4648_H_INCLUDED
|
||||||
|
#define CRYB_RFC4648_H_INCLUDED
|
||||||
|
|
||||||
|
/* estimate of output length for base32 encoding / decoding */
|
||||||
|
#define base32_enclen(l) (size_t)(((l + 4) / 5) * 8)
|
||||||
|
#define base32_declen(l) (size_t)(((l + 7) / 8) * 5)
|
||||||
|
|
||||||
|
/* base32 encoding / decoding */
|
||||||
|
#define base32_encode cryb_base32_encode
|
||||||
|
#define base32_decode cryb_base32_decode
|
||||||
|
int base32_encode(const uint8_t *, size_t, char *, size_t *);
|
||||||
|
int base32_decode(const char *, size_t, uint8_t *, size_t *);
|
||||||
|
|
||||||
|
/* estimate of output length for base64 encoding / decoding */
|
||||||
|
#define base64_enclen(l) (size_t)(((l + 2) / 3) * 4)
|
||||||
|
#define base64_declen(l) (size_t)(((l + 3) / 4) * 3)
|
||||||
|
|
||||||
|
/* base64 encoding / decoding */
|
||||||
|
#define base64_encode cryb_base64_encode
|
||||||
|
#define base64_decode cryb_base64_decode
|
||||||
|
int base64_encode(const uint8_t *, size_t, char *, size_t *);
|
||||||
|
int base64_decode(const char *, size_t, uint8_t *, size_t *);
|
||||||
|
|
||||||
|
#endif
|
57
include/cryb/sha1.h
Normal file
57
include/cryb/sha1.h
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2012 Universitetet i Oslo
|
||||||
|
* Copyright (c) 2012 Dag-Erling Smørgrav
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote
|
||||||
|
* products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Dag-Erling Smørgrav <des@des.no>
|
||||||
|
* Sponsor: the University of Oslo
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CRYB_SHA1_H_INCLUDED
|
||||||
|
#define CRYB_SHA1_H_INCLUDED
|
||||||
|
|
||||||
|
#define SHA1_DIGEST_LEN 20
|
||||||
|
|
||||||
|
typedef struct sha1_ctx {
|
||||||
|
uint8_t block[64];
|
||||||
|
size_t blocklen;
|
||||||
|
uint64_t bitlen;
|
||||||
|
uint32_t h[5], k[4];
|
||||||
|
} sha1_ctx;
|
||||||
|
|
||||||
|
#define sha1_init cryb_sha1_init
|
||||||
|
#define sha1_update cryb_sha1_update
|
||||||
|
#define sha1_final cryb_sha1_final
|
||||||
|
#define sha1_complete cryb_sha1_complete
|
||||||
|
void sha1_init(sha1_ctx *);
|
||||||
|
void sha1_update(sha1_ctx *, const void *, size_t);
|
||||||
|
void sha1_final(sha1_ctx *, void *);
|
||||||
|
void sha1_complete(const void *, size_t, void *);
|
||||||
|
|
||||||
|
#endif
|
43
include/cryb/strlcat.h
Normal file
43
include/cryb/strlcat.h
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2011 Dag-Erling Smørgrav
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote
|
||||||
|
* products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Dag-Erling Smørgrav <des@des.no>
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef OPENPAM_STRLCAT_H_INCLUDED
|
||||||
|
#define OPENPAM_STRLCAT_H_INCLUDED
|
||||||
|
|
||||||
|
#ifndef HAVE_STRLCAT
|
||||||
|
size_t cryb_strlcat(char *, const char *, size_t);
|
||||||
|
#undef strlcat
|
||||||
|
#define strlcat(arg, ...) cryb_strlcat(arg, __VA_ARGS__)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
43
include/cryb/strlcmp.h
Normal file
43
include/cryb/strlcmp.h
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2011 Dag-Erling Smørgrav
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote
|
||||||
|
* products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Dag-Erling Smørgrav <des@des.no>
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CRYB_STRLCMP_H_INCLUDED
|
||||||
|
#define CRYB_STRLCMP_H_INCLUDED
|
||||||
|
|
||||||
|
#ifndef HAVE_STRLCMP
|
||||||
|
int cryb_strlcmp(const char *, const char *, size_t);
|
||||||
|
#undef strlcmp
|
||||||
|
#define strlcmp(...) cryb_strlcmp(__VA_ARGS__)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
43
include/cryb/strlcpy.h
Normal file
43
include/cryb/strlcpy.h
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2011 Dag-Erling Smørgrav
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote
|
||||||
|
* products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Dag-Erling Smørgrav <des@des.no>
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef OPENPAM_STRLCPY_H_INCLUDED
|
||||||
|
#define OPENPAM_STRLCPY_H_INCLUDED
|
||||||
|
|
||||||
|
#ifndef HAVE_STRLCPY
|
||||||
|
size_t cryb_strlcpy(char *, const char *, size_t);
|
||||||
|
#undef strlcpy
|
||||||
|
#define strlcpy(arg, ...) cryb_strlcpy(arg, __VA_ARGS__)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
37
include/cryb/to.h
Normal file
37
include/cryb/to.h
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2014 Dag-Erling Smørgrav
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote
|
||||||
|
* products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Dag-Erling Smørgrav <des@des.no>
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CRYB_TO_H_INCLUDED
|
||||||
|
#define CRYB_TO_H_INCLUDED
|
||||||
|
|
||||||
|
#endif
|
39
include/cryb/totp.h
Normal file
39
include/cryb/totp.h
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2012 Universitetet i Oslo
|
||||||
|
* Copyright (c) 2012 Dag-Erling Smørgrav
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote
|
||||||
|
* products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Dag-Erling Smørgrav <des@des.no>
|
||||||
|
* Sponsor: the University of Oslo
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CRYB_TOTP_H_INCLUDED
|
||||||
|
#define CRYB_TOTP_H_INCLUDED
|
||||||
|
|
||||||
|
#endif
|
39
include/cryb/version.h
Normal file
39
include/cryb/version.h
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2014 Dag-Erling Smørgrav
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote
|
||||||
|
* products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Dag-Erling Smørgrav <des@des.no>
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CRYB_VERSION_H_INCLUDED
|
||||||
|
#define CRYB_VERSION_H_INCLUDED
|
||||||
|
|
||||||
|
#define CRYB_VERSION 20140311
|
||||||
|
|
||||||
|
#endif
|
13
lib/Makefile.am
Normal file
13
lib/Makefile.am
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
# $Id$
|
||||||
|
|
||||||
|
SUBDIRS = \
|
||||||
|
core \
|
||||||
|
digest \
|
||||||
|
enc \
|
||||||
|
mac \
|
||||||
|
rand \
|
||||||
|
oath
|
||||||
|
|
||||||
|
if WITH_RSAREF
|
||||||
|
SUBDIRS += rsaref
|
||||||
|
endif
|
11
lib/core/Makefile.am
Normal file
11
lib/core/Makefile.am
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
# $Id$
|
||||||
|
|
||||||
|
AM_CPPFLAGS = -I$(top_srcdir)/include
|
||||||
|
|
||||||
|
lib_LTLIBRARIES = libcryb-core.la
|
||||||
|
|
||||||
|
libcryb_core_la_SOURCES = \
|
||||||
|
cryb_core.c \
|
||||||
|
cryb_strlcat.c \
|
||||||
|
cryb_strlcpy.c \
|
||||||
|
cryb_strlcmp.c
|
36
lib/core/cryb_core.c
Normal file
36
lib/core/cryb_core.c
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2014 Dag-Erling Smørgrav
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote
|
||||||
|
* products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Dag-Erling Smørgrav <des@des.no>
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "cryb/impl.h"
|
||||||
|
|
||||||
|
#include <cryb/to.h>
|
54
lib/core/cryb_strlcat.c
Normal file
54
lib/core/cryb_strlcat.c
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2011-2012 Dag-Erling Smørgrav
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote
|
||||||
|
* products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Dag-Erling Smørgrav <des@des.no>
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "cryb/impl.h"
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#include <cryb/strlcat.h>
|
||||||
|
|
||||||
|
/* like strcat(3), but always NUL-terminates; returns strlen(src) */
|
||||||
|
size_t
|
||||||
|
cryb_strlcat(char *dst, const char *src, size_t size)
|
||||||
|
{
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
for (len = 0; *dst && size > 1; ++len, --size)
|
||||||
|
dst++;
|
||||||
|
for (; *src && size > 1; ++len, --size)
|
||||||
|
*dst++ = *src++;
|
||||||
|
*dst = '\0';
|
||||||
|
while (*src)
|
||||||
|
++len, ++src;
|
||||||
|
return (len);
|
||||||
|
}
|
49
lib/core/cryb_strlcmp.c
Normal file
49
lib/core/cryb_strlcmp.c
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2014 Dag-Erling Smørgrav
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote
|
||||||
|
* products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Dag-Erling Smørgrav <des@des.no>
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "cryb/impl.h"
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#include <cryb/strlcmp.h>
|
||||||
|
|
||||||
|
/* like strcmp, but only compares up to len characters */
|
||||||
|
int
|
||||||
|
cryb_strlcmp(const char *s1, const char *s2, size_t len)
|
||||||
|
{
|
||||||
|
|
||||||
|
for (; len && *s1 && *s2; --len, ++s1, ++s2)
|
||||||
|
if (*s1 != *s2)
|
||||||
|
return ((unsigned char)*s1 - (unsigned char)*s2);
|
||||||
|
return ((unsigned char)*s1);
|
||||||
|
}
|
52
lib/core/cryb_strlcpy.c
Normal file
52
lib/core/cryb_strlcpy.c
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2011-2012 Dag-Erling Smørgrav
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote
|
||||||
|
* products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Dag-Erling Smørgrav <des@des.no>
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "cryb/impl.h"
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#include <cryb/strlcpy.h>
|
||||||
|
|
||||||
|
/* like strcpy(3), but always NUL-terminates; returns strlen(src) */
|
||||||
|
size_t
|
||||||
|
cryb_strlcpy(char *dst, const char *src, size_t size)
|
||||||
|
{
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
for (len = 0; *src && size > 1; ++len, --size)
|
||||||
|
*dst++ = *src++;
|
||||||
|
*dst = '\0';
|
||||||
|
while (*src)
|
||||||
|
++len, ++src;
|
||||||
|
return (len);
|
||||||
|
}
|
9
lib/digest/Makefile.am
Normal file
9
lib/digest/Makefile.am
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
# $Id$
|
||||||
|
|
||||||
|
AM_CPPFLAGS = -I$(top_srcdir)/include
|
||||||
|
|
||||||
|
lib_LTLIBRARIES = libcryb-digest.la
|
||||||
|
|
||||||
|
libcryb_digest_la_SOURCES = \
|
||||||
|
md5.c \
|
||||||
|
sha1.c
|
69
lib/digest/digest.c
Normal file
69
lib/digest/digest.c
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2012 Universitetet i Oslo
|
||||||
|
* Copyright (c) 2012 Dag-Erling Smørgrav
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote
|
||||||
|
* products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Dag-Erling Smørgrav <des@des.no>
|
||||||
|
* Sponsor: the University of Oslo
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "cryb/impl.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <cryb/digest.h>
|
||||||
|
#include <cryb/md5.h>
|
||||||
|
#include <cryb/sha1.h>
|
||||||
|
|
||||||
|
static const struct digest_algorithm **cryb_digest_algorithms;
|
||||||
|
|
||||||
|
static void
|
||||||
|
cryb_init_digest_algorithms(void)
|
||||||
|
{
|
||||||
|
static const struct digest_algorithm *algorithms[] = {
|
||||||
|
&cryb_md5_algorithm,
|
||||||
|
&cryb_sha1_algorithm,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
cryb_digest_algorithms = algorithms;
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct digest_algorithm *
|
||||||
|
cryb_digest_algorithm(const char *name)
|
||||||
|
{
|
||||||
|
const struct digest_algorithm **algp;
|
||||||
|
|
||||||
|
if (cryb_digest_algorithms == NULL)
|
||||||
|
cryb_init_digest_algorithms();
|
||||||
|
for (algp = cryb_digest_algorithms; *algp != NULL; ++algp)
|
||||||
|
if (strcasecmp((*algp)->name, name) == 0)
|
||||||
|
return (*algp);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
261
lib/digest/md5.c
Normal file
261
lib/digest/md5.c
Normal file
|
@ -0,0 +1,261 @@
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2012 Universitetet i Oslo
|
||||||
|
* Copyright (c) 2012-2014 Dag-Erling Smørgrav
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote
|
||||||
|
* products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Dag-Erling Smørgrav <des@des.no>
|
||||||
|
* Sponsor: the University of Oslo
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "cryb/impl.h"
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_SYS_ENDIAN_H
|
||||||
|
#include <sys/endian.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_ENDIAN_H
|
||||||
|
#define _BSD_SOURCE
|
||||||
|
#include <endian.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <cryb/digest.h>
|
||||||
|
#include <cryb/bitwise.h>
|
||||||
|
#include <cryb/md5.h>
|
||||||
|
|
||||||
|
/* initial state */
|
||||||
|
static const uint32_t md5_h[4] = {
|
||||||
|
0x67452301U, 0xefcdab89U, 0x98badcfeU, 0x10325476U,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const uint32_t md5_k[64] = {
|
||||||
|
0xd76aa478U, 0xe8c7b756U, 0x242070dbU, 0xc1bdceeeU,
|
||||||
|
0xf57c0fafU, 0x4787c62aU, 0xa8304613U, 0xfd469501U,
|
||||||
|
0x698098d8U, 0x8b44f7afU, 0xffff5bb1U, 0x895cd7beU,
|
||||||
|
0x6b901122U, 0xfd987193U, 0xa679438eU, 0x49b40821U,
|
||||||
|
0xf61e2562U, 0xc040b340U, 0x265e5a51U, 0xe9b6c7aaU,
|
||||||
|
0xd62f105dU, 0x02441453U, 0xd8a1e681U, 0xe7d3fbc8U,
|
||||||
|
0x21e1cde6U, 0xc33707d6U, 0xf4d50d87U, 0x455a14edU,
|
||||||
|
0xa9e3e905U, 0xfcefa3f8U, 0x676f02d9U, 0x8d2a4c8aU,
|
||||||
|
0xfffa3942U, 0x8771f681U, 0x6d9d6122U, 0xfde5380cU,
|
||||||
|
0xa4beea44U, 0x4bdecfa9U, 0xf6bb4b60U, 0xbebfbc70U,
|
||||||
|
0x289b7ec6U, 0xeaa127faU, 0xd4ef3085U, 0x04881d05U,
|
||||||
|
0xd9d4d039U, 0xe6db99e5U, 0x1fa27cf8U, 0xc4ac5665U,
|
||||||
|
0xf4292244U, 0x432aff97U, 0xab9423a7U, 0xfc93a039U,
|
||||||
|
0x655b59c3U, 0x8f0ccc92U, 0xffeff47dU, 0x85845dd1U,
|
||||||
|
0x6fa87e4fU, 0xfe2ce6e0U, 0xa3014314U, 0x4e0811a1U,
|
||||||
|
0xf7537e82U, 0xbd3af235U, 0x2ad7d2bbU, 0xeb86d391U,
|
||||||
|
};
|
||||||
|
|
||||||
|
void
|
||||||
|
md5_init(struct md5_ctx *ctx)
|
||||||
|
{
|
||||||
|
|
||||||
|
memset(ctx, 0, sizeof *ctx);
|
||||||
|
memcpy(ctx->h, md5_h, sizeof ctx->h);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define md5_f(i, a, b, c, d, x, s) do { \
|
||||||
|
(a) += (((b) & (c)) | (~(b) & (d))); \
|
||||||
|
(a) += (x)[(i)] + md5_k[(i)]; \
|
||||||
|
(a) = rol((a), (s)) + (b); \
|
||||||
|
++(i); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define md5_g(i, a, b, c, d, x, s) do { \
|
||||||
|
(a) += (((b) & (d)) | ((c) & ~(d))); \
|
||||||
|
(a) += (x)[(5 * (i) + 1) % 16] + md5_k[(i)]; \
|
||||||
|
(a) = rol((a), (s)) + (b); \
|
||||||
|
++(i); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define md5_h(i, a, b, c, d, x, s) do { \
|
||||||
|
(a) += ((b) ^ (c) ^ (d)); \
|
||||||
|
(a) += (x)[(3 * (i) + 5) % 16] + md5_k[(i)]; \
|
||||||
|
(a) = rol((a), (s)) + (b); \
|
||||||
|
++(i); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define md5_i(i, a, b, c, d, x, s) do { \
|
||||||
|
(a) += ((c) ^ ((b) | ~(d))); \
|
||||||
|
(a) += (x)[(7 * (i)) % 16] + md5_k[(i)]; \
|
||||||
|
(a) = rol((a), (s)) + (b); \
|
||||||
|
++(i); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
static void
|
||||||
|
md5_compute(struct md5_ctx *ctx, const uint8_t *block)
|
||||||
|
{
|
||||||
|
uint32_t w[16], a, b, c, d;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
memcpy(w, block, 64);
|
||||||
|
#if WORDS_BIGENDIAN
|
||||||
|
for (i = 0; i < 16; ++i)
|
||||||
|
w[i] = le32toh(w[i]);
|
||||||
|
#endif
|
||||||
|
a = ctx->h[0];
|
||||||
|
b = ctx->h[1];
|
||||||
|
c = ctx->h[2];
|
||||||
|
d = ctx->h[3];
|
||||||
|
i = 0;
|
||||||
|
|
||||||
|
md5_f(i, a, b, c, d, w, 7);
|
||||||
|
md5_f(i, d, a, b, c, w, 12);
|
||||||
|
md5_f(i, c, d, a, b, w, 17);
|
||||||
|
md5_f(i, b, c, d, a, w, 22);
|
||||||
|
md5_f(i, a, b, c, d, w, 7);
|
||||||
|
md5_f(i, d, a, b, c, w, 12);
|
||||||
|
md5_f(i, c, d, a, b, w, 17);
|
||||||
|
md5_f(i, b, c, d, a, w, 22);
|
||||||
|
md5_f(i, a, b, c, d, w, 7);
|
||||||
|
md5_f(i, d, a, b, c, w, 12);
|
||||||
|
md5_f(i, c, d, a, b, w, 17);
|
||||||
|
md5_f(i, b, c, d, a, w, 22);
|
||||||
|
md5_f(i, a, b, c, d, w, 7);
|
||||||
|
md5_f(i, d, a, b, c, w, 12);
|
||||||
|
md5_f(i, c, d, a, b, w, 17);
|
||||||
|
md5_f(i, b, c, d, a, w, 22);
|
||||||
|
|
||||||
|
md5_g(i, a, b, c, d, w, 5);
|
||||||
|
md5_g(i, d, a, b, c, w, 9);
|
||||||
|
md5_g(i, c, d, a, b, w, 14);
|
||||||
|
md5_g(i, b, c, d, a, w, 20);
|
||||||
|
md5_g(i, a, b, c, d, w, 5);
|
||||||
|
md5_g(i, d, a, b, c, w, 9);
|
||||||
|
md5_g(i, c, d, a, b, w, 14);
|
||||||
|
md5_g(i, b, c, d, a, w, 20);
|
||||||
|
md5_g(i, a, b, c, d, w, 5);
|
||||||
|
md5_g(i, d, a, b, c, w, 9);
|
||||||
|
md5_g(i, c, d, a, b, w, 14);
|
||||||
|
md5_g(i, b, c, d, a, w, 20);
|
||||||
|
md5_g(i, a, b, c, d, w, 5);
|
||||||
|
md5_g(i, d, a, b, c, w, 9);
|
||||||
|
md5_g(i, c, d, a, b, w, 14);
|
||||||
|
md5_g(i, b, c, d, a, w, 20);
|
||||||
|
|
||||||
|
md5_h(i, a, b, c, d, w, 4);
|
||||||
|
md5_h(i, d, a, b, c, w, 11);
|
||||||
|
md5_h(i, c, d, a, b, w, 16);
|
||||||
|
md5_h(i, b, c, d, a, w, 23);
|
||||||
|
md5_h(i, a, b, c, d, w, 4);
|
||||||
|
md5_h(i, d, a, b, c, w, 11);
|
||||||
|
md5_h(i, c, d, a, b, w, 16);
|
||||||
|
md5_h(i, b, c, d, a, w, 23);
|
||||||
|
md5_h(i, a, b, c, d, w, 4);
|
||||||
|
md5_h(i, d, a, b, c, w, 11);
|
||||||
|
md5_h(i, c, d, a, b, w, 16);
|
||||||
|
md5_h(i, b, c, d, a, w, 23);
|
||||||
|
md5_h(i, a, b, c, d, w, 4);
|
||||||
|
md5_h(i, d, a, b, c, w, 11);
|
||||||
|
md5_h(i, c, d, a, b, w, 16);
|
||||||
|
md5_h(i, b, c, d, a, w, 23);
|
||||||
|
|
||||||
|
md5_i(i, a, b, c, d, w, 6);
|
||||||
|
md5_i(i, d, a, b, c, w, 10);
|
||||||
|
md5_i(i, c, d, a, b, w, 15);
|
||||||
|
md5_i(i, b, c, d, a, w, 21);
|
||||||
|
md5_i(i, a, b, c, d, w, 6);
|
||||||
|
md5_i(i, d, a, b, c, w, 10);
|
||||||
|
md5_i(i, c, d, a, b, w, 15);
|
||||||
|
md5_i(i, b, c, d, a, w, 21);
|
||||||
|
md5_i(i, a, b, c, d, w, 6);
|
||||||
|
md5_i(i, d, a, b, c, w, 10);
|
||||||
|
md5_i(i, c, d, a, b, w, 15);
|
||||||
|
md5_i(i, b, c, d, a, w, 21);
|
||||||
|
md5_i(i, a, b, c, d, w, 6);
|
||||||
|
md5_i(i, d, a, b, c, w, 10);
|
||||||
|
md5_i(i, c, d, a, b, w, 15);
|
||||||
|
md5_i(i, b, c, d, a, w, 21);
|
||||||
|
|
||||||
|
ctx->h[0] += a;
|
||||||
|
ctx->h[1] += b;
|
||||||
|
ctx->h[2] += c;
|
||||||
|
ctx->h[3] += d;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
md5_update(struct md5_ctx *ctx, const void *buf, size_t len)
|
||||||
|
{
|
||||||
|
size_t copylen;
|
||||||
|
|
||||||
|
while (len) {
|
||||||
|
if (ctx->blocklen > 0 || len < 64) {
|
||||||
|
copylen = 64 - ctx->blocklen;
|
||||||
|
if (copylen > len)
|
||||||
|
copylen = len;
|
||||||
|
memcpy(ctx->block + ctx->blocklen, buf, copylen);
|
||||||
|
ctx->blocklen += copylen;
|
||||||
|
if (ctx->blocklen == 64) {
|
||||||
|
md5_compute(ctx, ctx->block);
|
||||||
|
ctx->blocklen = 0;
|
||||||
|
memset(ctx->block, 0, 64);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
copylen = 64;
|
||||||
|
md5_compute(ctx, buf);
|
||||||
|
}
|
||||||
|
ctx->bitlen += copylen * 8;
|
||||||
|
buf += copylen;
|
||||||
|
len -= copylen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
md5_final(struct md5_ctx *ctx, void *digest)
|
||||||
|
{
|
||||||
|
|
||||||
|
ctx->block[ctx->blocklen++] = 0x80;
|
||||||
|
if (ctx->blocklen > 56) {
|
||||||
|
md5_compute(ctx, ctx->block);
|
||||||
|
ctx->blocklen = 0;
|
||||||
|
memset(ctx->block, 0, 64);
|
||||||
|
}
|
||||||
|
le32enc(ctx->block + 56, ctx->bitlen & 0xffffffffUL);
|
||||||
|
le32enc(ctx->block + 60, ctx->bitlen >> 32);
|
||||||
|
md5_compute(ctx, ctx->block);
|
||||||
|
le32enc(digest, ctx->h[0]);
|
||||||
|
le32enc(digest + 4, ctx->h[1]);
|
||||||
|
le32enc(digest + 8, ctx->h[2]);
|
||||||
|
le32enc(digest + 12, ctx->h[3]);
|
||||||
|
memset(ctx, 0, sizeof *ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
md5_complete(const void *buf, size_t len, void *digest)
|
||||||
|
{
|
||||||
|
struct md5_ctx ctx;
|
||||||
|
|
||||||
|
md5_init(&ctx);
|
||||||
|
md5_update(&ctx, buf, len);
|
||||||
|
md5_final(&ctx, digest);
|
||||||
|
}
|
173
lib/digest/sha1.c
Normal file
173
lib/digest/sha1.c
Normal file
|
@ -0,0 +1,173 @@
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2012 Universitetet i Oslo
|
||||||
|
* Copyright (c) 2012-2014 Dag-Erling Smørgrav
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote
|
||||||
|
* products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Dag-Erling Smørgrav <des@des.no>
|
||||||
|
* Sponsor: the University of Oslo
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "cryb/impl.h"
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_SYS_ENDIAN_H
|
||||||
|
#include <sys/endian.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_ENDIAN_H
|
||||||
|
#define _BSD_SOURCE
|
||||||
|
#include <endian.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <cryb/digest.h>
|
||||||
|
#include <cryb/bitwise.h>
|
||||||
|
|
||||||
|
#include <cryb/sha1.h>
|
||||||
|
|
||||||
|
static uint32_t sha1_h[5] = {
|
||||||
|
0x67452301U, 0xefcdab89U, 0x98badcfeU, 0x10325476U, 0xc3d2e1f0U,
|
||||||
|
};
|
||||||
|
|
||||||
|
static uint32_t sha1_k[4] = {
|
||||||
|
0x5a827999U, 0x6ed9eba1U, 0x8f1bbcdcU, 0xca62c1d6U,
|
||||||
|
};
|
||||||
|
|
||||||
|
void
|
||||||
|
sha1_init(struct sha1_ctx *ctx)
|
||||||
|
{
|
||||||
|
|
||||||
|
memset(ctx, 0, sizeof *ctx);
|
||||||
|
memcpy(ctx->h, sha1_h, sizeof ctx->h);
|
||||||
|
memcpy(ctx->k, sha1_k, sizeof ctx->k);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
sha1_compute(struct sha1_ctx *ctx, const uint8_t *block)
|
||||||
|
{
|
||||||
|
uint32_t w[80], a, b, c, d, e, f, temp;
|
||||||
|
|
||||||
|
memcpy(w, block, 64);
|
||||||
|
#if !WORDS_BIGENDIAN
|
||||||
|
for (int i = 0; i < 16; ++i)
|
||||||
|
w[i] = be32toh(w[i]);
|
||||||
|
#endif
|
||||||
|
for (int i = 16; i < 80; ++i) {
|
||||||
|
w[i] = w[i-3] ^ w[i-8] ^ w[i-14] ^ w[i-16];
|
||||||
|
w[i] = rol(w[i], 1);
|
||||||
|
}
|
||||||
|
a = ctx->h[0];
|
||||||
|
b = ctx->h[1];
|
||||||
|
c = ctx->h[2];
|
||||||
|
d = ctx->h[3];
|
||||||
|
e = ctx->h[4];
|
||||||
|
for (int t = 0; t < 80; ++t) {
|
||||||
|
if (t < 20)
|
||||||
|
f = (b & c) | ((~b) & d);
|
||||||
|
else if (t < 40)
|
||||||
|
f = b ^ c ^ d;
|
||||||
|
else if (t < 60)
|
||||||
|
f = (b & c) | (b & d) | (c & d);
|
||||||
|
else
|
||||||
|
f = b ^ c ^ d;
|
||||||
|
temp = rol(a, 5) + f + e + w[t] + ctx->k[t/20];
|
||||||
|
e = d;
|
||||||
|
d = c;
|
||||||
|
c = ror(b, 2);
|
||||||
|
b = a;
|
||||||
|
a = temp;
|
||||||
|
}
|
||||||
|
ctx->h[0] += a;
|
||||||
|
ctx->h[1] += b;
|
||||||
|
ctx->h[2] += c;
|
||||||
|
ctx->h[3] += d;
|
||||||
|
ctx->h[4] += e;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sha1_update(struct sha1_ctx *ctx, const void *buf, size_t len)
|
||||||
|
{
|
||||||
|
size_t copylen;
|
||||||
|
|
||||||
|
while (len) {
|
||||||
|
if (ctx->blocklen > 0 || len < 64) {
|
||||||
|
copylen = sizeof ctx->block - ctx->blocklen;
|
||||||
|
if (copylen > len)
|
||||||
|
copylen = len;
|
||||||
|
memcpy(ctx->block + ctx->blocklen, buf, copylen);
|
||||||
|
ctx->blocklen += copylen;
|
||||||
|
if (ctx->blocklen == 64) {
|
||||||
|
sha1_compute(ctx, ctx->block);
|
||||||
|
ctx->blocklen = 0;
|
||||||
|
memset(ctx->block, 0, 64);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
copylen = 64;
|
||||||
|
sha1_compute(ctx, buf);
|
||||||
|
}
|
||||||
|
ctx->bitlen += copylen * 8;
|
||||||
|
buf += copylen;
|
||||||
|
len -= copylen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sha1_final(struct sha1_ctx *ctx, void *digest)
|
||||||
|
{
|
||||||
|
uint32_t hi, lo;
|
||||||
|
|
||||||
|
ctx->block[ctx->blocklen++] = 0x80;
|
||||||
|
if (ctx->blocklen > 56) {
|
||||||
|
sha1_compute(ctx, ctx->block);
|
||||||
|
ctx->blocklen = 0;
|
||||||
|
memset(ctx->block, 0, 64);
|
||||||
|
}
|
||||||
|
hi = htobe32(ctx->bitlen >> 32);
|
||||||
|
lo = htobe32(ctx->bitlen & 0xffffffffUL);
|
||||||
|
memcpy(ctx->block + 56, &hi, 4);
|
||||||
|
memcpy(ctx->block + 60, &lo, 4);
|
||||||
|
ctx->blocklen = 64;
|
||||||
|
sha1_compute(ctx, ctx->block);
|
||||||
|
for (int i = 0; i < 5; ++i)
|
||||||
|
ctx->h[i] = htobe32(ctx->h[i]);
|
||||||
|
memcpy(digest, ctx->h, 20);
|
||||||
|
memset(ctx, 0, sizeof *ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sha1_complete(const void *buf, size_t len, void *digest)
|
||||||
|
{
|
||||||
|
struct sha1_ctx ctx;
|
||||||
|
|
||||||
|
sha1_init(&ctx);
|
||||||
|
sha1_update(&ctx, buf, len);
|
||||||
|
sha1_final(&ctx, digest);
|
||||||
|
}
|
10
lib/enc/Makefile.am
Normal file
10
lib/enc/Makefile.am
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
# $Id$
|
||||||
|
|
||||||
|
AM_CPPFLAGS = -I$(top_srcdir)/include
|
||||||
|
|
||||||
|
lib_LTLIBRARIES = libcryb-enc.la
|
||||||
|
|
||||||
|
libcryb_enc_la_SOURCES = \
|
||||||
|
cryb_base32.c \
|
||||||
|
cryb_base64.c \
|
||||||
|
cryb_percent.c
|
201
lib/enc/cryb_base32.c
Normal file
201
lib/enc/cryb_base32.c
Normal file
|
@ -0,0 +1,201 @@
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2013-2014 Universitetet i Oslo
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote
|
||||||
|
* products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Dag-Erling Smørgrav <des@des.no>
|
||||||
|
* Sponsor: the University of Oslo
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "cryb/impl.h"
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <cryb/rfc4648.h>
|
||||||
|
|
||||||
|
static const char b32enc[] =
|
||||||
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
|
||||||
|
|
||||||
|
static const char b32dec[256] = {
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
|
||||||
|
0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
|
||||||
|
0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
|
||||||
|
0x17, 0x18, 0x19, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Encode data in RFC 4648 base 32 representation. The target buffer must
|
||||||
|
* have room for base32_enclen(len) characters and a terminating NUL.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
base32_encode(const uint8_t *in, size_t ilen, char *out, size_t *olen)
|
||||||
|
{
|
||||||
|
uint64_t bits;
|
||||||
|
|
||||||
|
if (*olen <= base32_enclen(ilen)) {
|
||||||
|
*olen = base32_enclen(ilen) + 1;
|
||||||
|
errno = ENOSPC;
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
*olen = base32_enclen(ilen) + 1;
|
||||||
|
while (ilen >= 5) {
|
||||||
|
bits = 0;
|
||||||
|
bits |= (uint64_t)*in++ << 32;
|
||||||
|
bits |= (uint64_t)*in++ << 24;
|
||||||
|
bits |= (uint64_t)*in++ << 16;
|
||||||
|
bits |= (uint64_t)*in++ << 8;
|
||||||
|
bits |= (uint64_t)*in++;
|
||||||
|
*out++ = b32enc[bits >> 35 & 0x1f];
|
||||||
|
*out++ = b32enc[bits >> 30 & 0x1f];
|
||||||
|
*out++ = b32enc[bits >> 25 & 0x1f];
|
||||||
|
*out++ = b32enc[bits >> 20 & 0x1f];
|
||||||
|
*out++ = b32enc[bits >> 15 & 0x1f];
|
||||||
|
*out++ = b32enc[bits >> 10 & 0x1f];
|
||||||
|
*out++ = b32enc[bits >> 5 & 0x1f];
|
||||||
|
*out++ = b32enc[bits & 0x1f];
|
||||||
|
ilen -= 5;
|
||||||
|
}
|
||||||
|
if (ilen > 0) {
|
||||||
|
bits = 0;
|
||||||
|
switch (ilen) {
|
||||||
|
case 4:
|
||||||
|
bits |= (uint64_t)in[3] << 8;
|
||||||
|
case 3:
|
||||||
|
bits |= (uint64_t)in[2] << 16;
|
||||||
|
case 2:
|
||||||
|
bits |= (uint64_t)in[1] << 24;
|
||||||
|
case 1:
|
||||||
|
bits |= (uint64_t)in[0] << 32;
|
||||||
|
CRYB_NO_DEFAULT_CASE
|
||||||
|
}
|
||||||
|
*out++ = b32enc[bits >> 35 & 0x1f];
|
||||||
|
*out++ = b32enc[bits >> 30 & 0x1f];
|
||||||
|
*out++ = ilen > 1 ? b32enc[bits >> 25 & 0x1f] : '=';
|
||||||
|
*out++ = ilen > 1 ? b32enc[bits >> 20 & 0x1f] : '=';
|
||||||
|
*out++ = ilen > 2 ? b32enc[bits >> 15 & 0x1f] : '=';
|
||||||
|
*out++ = ilen > 3 ? b32enc[bits >> 10 & 0x1f] : '=';
|
||||||
|
*out++ = ilen > 3 ? b32enc[bits >> 5 & 0x1f] : '=';
|
||||||
|
*out++ = '=';
|
||||||
|
}
|
||||||
|
*out++ = '\0';
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Decode data in RFC 4648 base 32 representation, stopping at the
|
||||||
|
* terminating NUL, the first invalid (non-base32, non-whitespace)
|
||||||
|
* character or after len characters, whichever comes first.
|
||||||
|
*
|
||||||
|
* Padding is handled sloppily: any padding character following the data
|
||||||
|
* is silently consumed. This not only simplifies the code but ensures
|
||||||
|
* compatibility with implementations which do not emit or understand
|
||||||
|
* padding.
|
||||||
|
*
|
||||||
|
* The olen argument is used by the caller to pass the size of the buffer
|
||||||
|
* and by base32_decode() to return the amount of data successfully
|
||||||
|
* decoded. If the buffer is too small, base32_decode() discards the
|
||||||
|
* excess data, but returns the total amount.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
base32_decode(const char *in, size_t ilen, uint8_t *out, size_t *olen)
|
||||||
|
{
|
||||||
|
size_t len;
|
||||||
|
int bits, shift, padding;
|
||||||
|
|
||||||
|
for (bits = shift = padding = len = 0; ilen && *in; --ilen, ++in) {
|
||||||
|
if (*in == ' ' || *in == '\t' || *in == '\r' || *in == '\n' ||
|
||||||
|
(padding && *in == '=')) {
|
||||||
|
/* consume */
|
||||||
|
continue;
|
||||||
|
} else if (!padding && b32dec[(uint8_t)*in] >= 0) {
|
||||||
|
/* shift into accumulator */
|
||||||
|
shift += 5;
|
||||||
|
bits = bits << 5 | b32dec[(uint8_t)*in];
|
||||||
|
} else if (!padding && *in == '=' &&
|
||||||
|
(shift == 1 || shift == 2 || shift == 3 || shift == 4)) {
|
||||||
|
/* final byte */
|
||||||
|
padding = 1;
|
||||||
|
} else {
|
||||||
|
/* error */
|
||||||
|
*olen = 0;
|
||||||
|
errno = EINVAL;
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
if (shift >= 8) {
|
||||||
|
/* output accumulated byte */
|
||||||
|
shift -= 8;
|
||||||
|
if (len++ < *olen)
|
||||||
|
*out++ = (bits >> shift) & 0xff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* non-zero bits in last byte before padding */
|
||||||
|
if (shift && (bits & ~(~0 << shift)) != 0) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
/* report decoded length */
|
||||||
|
if (len > *olen) {
|
||||||
|
/* overflow */
|
||||||
|
*olen = len;
|
||||||
|
errno = ENOSPC;
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
*olen = len;
|
||||||
|
return (0);
|
||||||
|
}
|
189
lib/enc/cryb_base64.c
Normal file
189
lib/enc/cryb_base64.c
Normal file
|
@ -0,0 +1,189 @@
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2013-2014 Universitetet i Oslo
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote
|
||||||
|
* products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Dag-Erling Smørgrav <des@des.no>
|
||||||
|
* Sponsor: the University of Oslo
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "cryb/impl.h"
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <cryb/rfc4648.h>
|
||||||
|
|
||||||
|
static const char b64enc[] =
|
||||||
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||||
|
"abcdefghijklmnopqrstuvwxyz"
|
||||||
|
"0123456789+/";
|
||||||
|
|
||||||
|
static const char b64dec[256] = {
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0x3e, 0xff, 0xff, 0xff, 0x3f,
|
||||||
|
0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
|
||||||
|
0x3c, 0x3d, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
|
||||||
|
0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
|
||||||
|
0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
|
||||||
|
0x17, 0x18, 0x19, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
|
||||||
|
0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
|
||||||
|
0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
|
||||||
|
0x31, 0x32, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Encode data in RFC 4648 base 64 representation. The target buffer must
|
||||||
|
* have room for base64_enclen(len) characters and a terminating NUL.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
base64_encode(const uint8_t *in, size_t ilen, char *out, size_t *olen)
|
||||||
|
{
|
||||||
|
uint32_t bits;
|
||||||
|
|
||||||
|
if (*olen <= base64_enclen(ilen)) {
|
||||||
|
*olen = base64_enclen(ilen) + 1;
|
||||||
|
errno = ENOSPC;
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
*olen = base64_enclen(ilen) + 1;
|
||||||
|
while (ilen >= 3) {
|
||||||
|
bits = 0;
|
||||||
|
bits |= (uint32_t)*in++ << 16;
|
||||||
|
bits |= (uint32_t)*in++ << 8;
|
||||||
|
bits |= (uint32_t)*in++;
|
||||||
|
ilen -= 3;
|
||||||
|
*out++ = b64enc[bits >> 18 & 0x3f];
|
||||||
|
*out++ = b64enc[bits >> 12 & 0x3f];
|
||||||
|
*out++ = b64enc[bits >> 6 & 0x3f];
|
||||||
|
*out++ = b64enc[bits & 0x3f];
|
||||||
|
}
|
||||||
|
if (ilen > 0) {
|
||||||
|
bits = 0;
|
||||||
|
switch (ilen) {
|
||||||
|
case 2:
|
||||||
|
bits |= (uint32_t)in[1] << 8;
|
||||||
|
case 1:
|
||||||
|
bits |= (uint32_t)in[0] << 16;
|
||||||
|
CRYB_NO_DEFAULT_CASE
|
||||||
|
}
|
||||||
|
*out++ = b64enc[bits >> 18 & 0x3f];
|
||||||
|
*out++ = b64enc[bits >> 12 & 0x3f];
|
||||||
|
*out++ = ilen > 1 ? b64enc[bits >> 6 & 0x3f] : '=';
|
||||||
|
*out++ = '=';
|
||||||
|
}
|
||||||
|
*out++ = '\0';
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Decode data in RFC 4648 base 64 representation, stopping at the
|
||||||
|
* terminating NUL, the first invalid (non-base64, non-whitespace)
|
||||||
|
* character or after len characters, whichever comes first.
|
||||||
|
*
|
||||||
|
* Padding is handled sloppily: any padding character following the data
|
||||||
|
* is silently consumed. This not only simplifies the code but ensures
|
||||||
|
* compatibility with implementations which do not emit or understand
|
||||||
|
* padding.
|
||||||
|
*
|
||||||
|
* The olen argument is used by the caller to pass the size of the buffer
|
||||||
|
* and by base64_decode() to return the amount of data successfully
|
||||||
|
* decoded. If the buffer is too small, base64_decode() discards the
|
||||||
|
* excess data, but returns the total amount.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
base64_decode(const char *in, size_t ilen, uint8_t *out, size_t *olen)
|
||||||
|
{
|
||||||
|
size_t len;
|
||||||
|
int bits, shift, padding;
|
||||||
|
|
||||||
|
for (bits = shift = padding = len = 0; ilen && *in; --ilen, ++in) {
|
||||||
|
if (*in == ' ' || *in == '\t' || *in == '\r' || *in == '\n' ||
|
||||||
|
(padding && *in == '=')) {
|
||||||
|
/* consume */
|
||||||
|
continue;
|
||||||
|
} else if (!padding && b64dec[(uint8_t)*in] >= 0) {
|
||||||
|
/* shift into accumulator */
|
||||||
|
shift += 6;
|
||||||
|
bits = bits << 6 | b64dec[(uint8_t)*in];
|
||||||
|
} else if (!padding && *in == '=' &&
|
||||||
|
(shift == 2 || shift == 4)) {
|
||||||
|
/* final byte */
|
||||||
|
padding = 1;
|
||||||
|
} else {
|
||||||
|
/* error */
|
||||||
|
*olen = 0;
|
||||||
|
errno = EINVAL;
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
if (shift >= 8) {
|
||||||
|
/* output accumulated byte */
|
||||||
|
shift -= 8;
|
||||||
|
if (len++ < *olen)
|
||||||
|
*out++ = (bits >> shift) & 0xff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* non-zero bits in last byte before padding */
|
||||||
|
if (shift && (bits & ~(~0 << shift)) != 0) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
/* report decoded length */
|
||||||
|
if (len > *olen) {
|
||||||
|
/* overflow */
|
||||||
|
*olen = len;
|
||||||
|
errno = ENOSPC;
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
*olen = len;
|
||||||
|
return (0);
|
||||||
|
}
|
115
lib/enc/cryb_percent.c
Normal file
115
lib/enc/cryb_percent.c
Normal file
|
@ -0,0 +1,115 @@
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2014 Dag-Erling Smørgrav
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote
|
||||||
|
* products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Dag-Erling Smørgrav <des@des.no>
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "cryb/impl.h"
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <cryb/ctype.h>
|
||||||
|
#include <cryb/rfc3986.h>
|
||||||
|
|
||||||
|
static const char hex[] = "0123456789ABCDEF";
|
||||||
|
|
||||||
|
#define unhex(ch) \
|
||||||
|
((ch >= '0' && ch <= '9') ? ch - '0' : \
|
||||||
|
(ch >= 'A' && ch <= 'F') ? 0xa + ch - 'A' : \
|
||||||
|
(ch >= 'a' && ch <= 'f') ? 0xa + ch - 'a' : 0)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Encodes a string in RFC 3986 percent-encoded representation.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
percent_encode(const char *in, size_t ilen, char *out, size_t *olen)
|
||||||
|
{
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
for (len = 0; ilen && *in; --ilen, ++in) {
|
||||||
|
if (is_uri(*in)) {
|
||||||
|
if (len++ < *olen)
|
||||||
|
*out++ = *in;
|
||||||
|
} else {
|
||||||
|
if (len++ < *olen)
|
||||||
|
*out++ = '%';
|
||||||
|
if (len++ < *olen)
|
||||||
|
*out++ = hex[(uint8_t)*in >> 4];
|
||||||
|
if (len++ < *olen)
|
||||||
|
*out++ = hex[(uint8_t)*in & 0xf];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (len < *olen)
|
||||||
|
*out = '\0';
|
||||||
|
if (len >= *olen) {
|
||||||
|
/* overflow */
|
||||||
|
*olen = len;
|
||||||
|
errno = ENOSPC;
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
*olen = len;
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Decodes a string in RFC 3986 percent-encoded representation.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
percent_decode(const char *in, size_t ilen, char *out, size_t *olen)
|
||||||
|
{
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
for (len = 0; ilen && *in; --ilen, ++in) {
|
||||||
|
if (*in != '%') {
|
||||||
|
if (++len < *olen)
|
||||||
|
*out++ = *in;
|
||||||
|
} else if (ilen >= 3 && is_xdigit(in[1]) && is_xdigit(in[2])) {
|
||||||
|
if (++len < *olen)
|
||||||
|
*out++ = unhex(in[1]) << 4 | unhex(in[2]);
|
||||||
|
in += 2;
|
||||||
|
} else {
|
||||||
|
errno = EINVAL;
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (len < *olen)
|
||||||
|
*out = '\0';
|
||||||
|
if (len >= *olen) {
|
||||||
|
/* overflow */
|
||||||
|
*olen = len;
|
||||||
|
errno = ENOSPC;
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
*olen = len;
|
||||||
|
return (0);
|
||||||
|
}
|
11
lib/mac/Makefile.am
Normal file
11
lib/mac/Makefile.am
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
# $Id$
|
||||||
|
|
||||||
|
AM_CPPFLAGS = -I$(top_srcdir)/include
|
||||||
|
|
||||||
|
lib_LTLIBRARIES = libcryb-mac.la
|
||||||
|
|
||||||
|
libcryb_mac_la_SOURCES = \
|
||||||
|
hmac.c
|
||||||
|
|
||||||
|
libcryb_mac_la_LIBADD = \
|
||||||
|
$(top_builddir)/lib/digest/libcryb-digest.la
|
110
lib/mac/hmac.c
Normal file
110
lib/mac/hmac.c
Normal file
|
@ -0,0 +1,110 @@
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2012 Universitetet i Oslo
|
||||||
|
* Copyright (c) 2012 Dag-Erling Smørgrav
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote
|
||||||
|
* products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Dag-Erling Smørgrav <des@des.no>
|
||||||
|
* Sponsor: the University of Oslo
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "cryb/impl.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_SYS_ENDIAN_H
|
||||||
|
#include <sys/endian.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_ENDIAN_H
|
||||||
|
#define _BSD_SOURCE
|
||||||
|
#include <endian.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <cryb/sha1.h>
|
||||||
|
#include <cryb/hmac.h>
|
||||||
|
|
||||||
|
void
|
||||||
|
hmac_init(struct hmac_ctx *ctx, const uint8_t *key, size_t keylen)
|
||||||
|
{
|
||||||
|
uint8_t ipad[64];
|
||||||
|
|
||||||
|
memset(ctx, 0, sizeof *ctx);
|
||||||
|
#if 1
|
||||||
|
if (keylen > sizeof ctx->key)
|
||||||
|
sha1_complete(key, keylen, ctx->key);
|
||||||
|
else
|
||||||
|
memcpy(ctx->key, key, keylen);
|
||||||
|
#else
|
||||||
|
uint8_t keybuf[sizeof ctx->key] = { 0 };
|
||||||
|
sha1_complete(key, keylen, keybuf);
|
||||||
|
if (keylen > sizeof ctx->key)
|
||||||
|
memcpy(ctx->key, keybuf, SHA1_DIGEST_LEN);
|
||||||
|
else
|
||||||
|
memcpy(ctx->key, key, keylen);
|
||||||
|
#endif
|
||||||
|
sha1_init(&ctx->sha1_ctx);
|
||||||
|
for (unsigned int i = 0; i < sizeof ipad; ++i)
|
||||||
|
ipad[i] = 0x36 ^ ctx->key[i];
|
||||||
|
sha1_update(&ctx->sha1_ctx, ipad, sizeof ipad);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
hmac_update(struct hmac_ctx *ctx, const uint8_t *buf, size_t len)
|
||||||
|
{
|
||||||
|
|
||||||
|
sha1_update(&ctx->sha1_ctx, buf, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
hmac_final(struct hmac_ctx *ctx, uint8_t *mac)
|
||||||
|
{
|
||||||
|
uint8_t digest[20], opad[64];
|
||||||
|
|
||||||
|
sha1_final(&ctx->sha1_ctx, digest);
|
||||||
|
for (unsigned int i = 0; i < sizeof opad; ++i)
|
||||||
|
opad[i] = 0x5c ^ ctx->key[i];
|
||||||
|
sha1_init(&ctx->sha1_ctx);
|
||||||
|
sha1_update(&ctx->sha1_ctx, opad, sizeof opad);
|
||||||
|
sha1_update(&ctx->sha1_ctx, digest, sizeof digest);
|
||||||
|
sha1_final(&ctx->sha1_ctx, mac);
|
||||||
|
memset(ctx, 0, sizeof *ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
hmac_complete(const uint8_t *key, size_t keylen,
|
||||||
|
const uint8_t *buf, size_t len, uint8_t *mac)
|
||||||
|
{
|
||||||
|
struct hmac_ctx ctx;
|
||||||
|
|
||||||
|
hmac_init(&ctx, key, keylen);
|
||||||
|
hmac_update(&ctx, buf, len);
|
||||||
|
hmac_final(&ctx, mac);
|
||||||
|
}
|
20
lib/oath/Makefile.am
Normal file
20
lib/oath/Makefile.am
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
# $Id$
|
||||||
|
|
||||||
|
AM_CPPFLAGS = -I$(top_srcdir)/include
|
||||||
|
|
||||||
|
lib_LTLIBRARIES = libcryb-oath.la
|
||||||
|
|
||||||
|
libcryb_oath_la_SOURCES = \
|
||||||
|
oath_hotp.c \
|
||||||
|
oath_totp.c \
|
||||||
|
oath_key_alloc.c \
|
||||||
|
oath_key_create.c \
|
||||||
|
oath_key_dummy.c \
|
||||||
|
oath_key_from_uri.c \
|
||||||
|
oath_key_free.c \
|
||||||
|
oath_key.c
|
||||||
|
|
||||||
|
libcryb_oath_la_LIBADD = \
|
||||||
|
$(top_builddir)/lib/digest/libcryb-digest.la \
|
||||||
|
$(top_builddir)/lib/mac/libcryb-mac.la \
|
||||||
|
$(top_builddir)/lib/enc/libcryb-enc.la
|
134
lib/oath/oath_hotp.c
Normal file
134
lib/oath/oath_hotp.c
Normal file
|
@ -0,0 +1,134 @@
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2012-2013 Universitetet i Oslo
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote
|
||||||
|
* products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Dag-Erling Smørgrav <des@des.no>
|
||||||
|
* Sponsor: the University of Oslo
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "cryb/impl.h"
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <cryb/sha1.h>
|
||||||
|
#include <cryb/hmac.h>
|
||||||
|
#include <cryb/oath.h>
|
||||||
|
|
||||||
|
#define StToNum(St) (St)
|
||||||
|
|
||||||
|
static uint32_t
|
||||||
|
DT(const uint8_t *String)
|
||||||
|
{
|
||||||
|
uint8_t OffsetBits;
|
||||||
|
int Offset;
|
||||||
|
uint32_t P;
|
||||||
|
|
||||||
|
OffsetBits = String[19] & 0x0f;
|
||||||
|
Offset = StToNum(OffsetBits);
|
||||||
|
P = (uint32_t)String[Offset + 0] << 24 |
|
||||||
|
(uint32_t)String[Offset + 1] << 16 |
|
||||||
|
(uint32_t)String[Offset + 2] << 8 |
|
||||||
|
(uint32_t)String[Offset + 3];
|
||||||
|
return (P & 0x7fffffffUL);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int
|
||||||
|
oath_hotp(const uint8_t *K, size_t Klen, uint64_t seq, unsigned int Digit)
|
||||||
|
{
|
||||||
|
hmac_ctx ctx;
|
||||||
|
uint8_t C[8];
|
||||||
|
uint8_t HS[20];
|
||||||
|
uint32_t Sbits, Snum;
|
||||||
|
unsigned int mod, D;
|
||||||
|
|
||||||
|
for (int i = 7; i >= 0; --i) {
|
||||||
|
C[i] = seq & 0xff;
|
||||||
|
seq >>= 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* HS = HMAC-SHA-1(K,C) */
|
||||||
|
hmac_init(&ctx, K, Klen);
|
||||||
|
hmac_update(&ctx, (const uint8_t *)&C, sizeof C);
|
||||||
|
hmac_final(&ctx, HS);
|
||||||
|
|
||||||
|
Sbits = DT(HS);
|
||||||
|
Snum = StToNum(Sbits);
|
||||||
|
for (mod = 1; Digit > 0; --Digit)
|
||||||
|
mod *= 10;
|
||||||
|
D = Snum % mod;
|
||||||
|
return (D);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Computes the current code for the given key and advances the counter.
|
||||||
|
*/
|
||||||
|
unsigned int
|
||||||
|
oath_hotp_current(struct oath_key *k)
|
||||||
|
{
|
||||||
|
unsigned int code;
|
||||||
|
|
||||||
|
if (k == NULL)
|
||||||
|
return (-1);
|
||||||
|
if (k->mode != om_hotp)
|
||||||
|
return (-1);
|
||||||
|
if (k->counter == UINT64_MAX)
|
||||||
|
return (-1);
|
||||||
|
code = oath_hotp(k->key, k->keylen, k->counter, k->digits);
|
||||||
|
k->counter += 1;
|
||||||
|
return (code);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Compares the code provided by the user with expected values within a
|
||||||
|
* given window. Returns 1 if there was a match, 0 if not, and -1 if an
|
||||||
|
* error occurred. Also advances the counter if there was a match.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
oath_hotp_match(struct oath_key *k, unsigned int response, int window)
|
||||||
|
{
|
||||||
|
unsigned int code;
|
||||||
|
|
||||||
|
if (k == NULL)
|
||||||
|
return (-1);
|
||||||
|
if (window < 1)
|
||||||
|
return (-1);
|
||||||
|
if (k->mode != om_hotp)
|
||||||
|
return (-1);
|
||||||
|
if (k->counter >= UINT64_MAX - window)
|
||||||
|
return (-1);
|
||||||
|
for (int i = 0; i < window; ++i) {
|
||||||
|
code = oath_hotp(k->key, k->keylen, k->counter + i, k->digits);
|
||||||
|
if (code == response && !k->dummy) {
|
||||||
|
k->counter = k->counter + i;
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (0);
|
||||||
|
}
|
55
lib/oath/oath_impl.h
Normal file
55
lib/oath/oath_impl.h
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2012-2013 Universitetet i Oslo
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote
|
||||||
|
* products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Dag-Erling Smørgrav <des@des.no>
|
||||||
|
* Sponsor: the University of Oslo
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef OATH_IMPL_H_INCLUDED
|
||||||
|
#define OATH_IMPL_H_INCLUDED
|
||||||
|
|
||||||
|
#if _BullseyeCoverage
|
||||||
|
#define COVERAGE_DISABLE _Pragma("BullseyeCoverage save off")
|
||||||
|
#define COVERAGE_RESTORE _Pragma("BullseyeCoverage restore")
|
||||||
|
#else
|
||||||
|
#define COVERAGE_DISABLE
|
||||||
|
#define COVERAGE_RESTORE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Use at end of switch which has no default case
|
||||||
|
*/
|
||||||
|
#define COVERAGE_NO_DEFAULT_CASE \
|
||||||
|
COVERAGE_DISABLE \
|
||||||
|
default: \
|
||||||
|
(void)0; \
|
||||||
|
COVERAGE_RESTORE
|
||||||
|
|
||||||
|
#endif
|
100
lib/oath/oath_key.c
Normal file
100
lib/oath/oath_key.c
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2013 Universitetet i Oslo
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote
|
||||||
|
* products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Dag-Erling Smørgrav <des@des.no>
|
||||||
|
* Sponsor: the University of Oslo
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "cryb/impl.h"
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <cryb/rfc4648.h>
|
||||||
|
#include <cryb/strlcmp.h>
|
||||||
|
#include <cryb/oath.h>
|
||||||
|
|
||||||
|
char *
|
||||||
|
oath_key_to_uri(const struct oath_key *key)
|
||||||
|
{
|
||||||
|
const char *hash;
|
||||||
|
char *tmp, *uri;
|
||||||
|
size_t kslen, urilen;
|
||||||
|
|
||||||
|
switch (key->hash) {
|
||||||
|
case oh_sha1:
|
||||||
|
hash = "SHA1";
|
||||||
|
break;
|
||||||
|
case oh_sha256:
|
||||||
|
hash = "SHA256";
|
||||||
|
break;
|
||||||
|
case oh_sha512:
|
||||||
|
hash = "SHA512";
|
||||||
|
break;
|
||||||
|
case oh_md5:
|
||||||
|
hash = "MD5";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* XXX the label should be URI-encoded */
|
||||||
|
if (key->mode == om_hotp) {
|
||||||
|
urilen = asprintf(&uri, "otpauth://%s/%s?"
|
||||||
|
"algorithm=%s&digits=%d&counter=%ju&secret=",
|
||||||
|
"hotp", key->label, hash, key->digits,
|
||||||
|
(uintmax_t)key->counter);
|
||||||
|
} else if (key->mode == om_totp) {
|
||||||
|
urilen = asprintf(&uri, "otpauth://%s/%s?"
|
||||||
|
"algorithm=%s&digits=%d&period=%u&lastused=%ju&secret=",
|
||||||
|
"totp", key->label, hash, key->digits, key->timestep,
|
||||||
|
(uintmax_t)key->lastused);
|
||||||
|
} else {
|
||||||
|
/* unreachable */
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* compute length of base32-encoded key and append it */
|
||||||
|
kslen = base32_enclen(key->keylen) + 1;
|
||||||
|
if ((tmp = realloc(uri, urilen + kslen)) == NULL) {
|
||||||
|
free(uri);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
uri = tmp;
|
||||||
|
if (base32_encode(key->key, key->keylen, uri + urilen, &kslen) != 0) {
|
||||||
|
free(uri);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (uri);
|
||||||
|
}
|
84
lib/oath/oath_key_alloc.c
Normal file
84
lib/oath/oath_key_alloc.c
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2013 Universitetet i Oslo
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote
|
||||||
|
* products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Dag-Erling Smørgrav <des@des.no>
|
||||||
|
* Sponsor: the University of Oslo
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "cryb/impl.h"
|
||||||
|
|
||||||
|
#include <sys/mman.h>
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <cryb/oath.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* OATH
|
||||||
|
*
|
||||||
|
* Allocates an OATH key structure
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct oath_key *
|
||||||
|
oath_key_alloc(void)
|
||||||
|
{
|
||||||
|
struct oath_key *key;
|
||||||
|
int prot, flags;
|
||||||
|
|
||||||
|
prot = PROT_READ|PROT_WRITE;
|
||||||
|
flags = MAP_ANON;
|
||||||
|
#ifdef MAP_NOCORE
|
||||||
|
flags |= MAP_NOCORE;
|
||||||
|
#endif
|
||||||
|
if ((key = mmap(NULL, sizeof *key, prot, flags, -1, 0)) != NULL) {
|
||||||
|
memset(key, 0, sizeof *key);
|
||||||
|
key->mapped = 1;
|
||||||
|
if (mlock(key, sizeof *key) == 0)
|
||||||
|
key->locked = 1;
|
||||||
|
} else {
|
||||||
|
/* openpam_log(PAM_LOG_ERROR, "mmap(): %m"); */
|
||||||
|
if ((key = calloc(sizeof *key, 1)) == NULL)
|
||||||
|
/* openpam_log(PAM_LOG_ERROR, "malloc(): %m") */;
|
||||||
|
}
|
||||||
|
return (key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The =oath_key_alloc function allocates and initializes an OATH key
|
||||||
|
* structure.
|
||||||
|
*
|
||||||
|
* Keys allocated with =oath_key_alloc must be freed using =oath_key_free.
|
||||||
|
*
|
||||||
|
* >oath_key_free
|
||||||
|
*
|
||||||
|
* AUTHOR UIO
|
||||||
|
*/
|
177
lib/oath/oath_key_create.c
Normal file
177
lib/oath/oath_key_create.c
Normal file
|
@ -0,0 +1,177 @@
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2013-2014 Universitetet i Oslo
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote
|
||||||
|
* products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Dag-Erling Smørgrav <des@des.no>
|
||||||
|
* Sponsor: the University of Oslo
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "cryb/impl.h"
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <cryb/oath.h>
|
||||||
|
#include <cryb/rand.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* OATH
|
||||||
|
*
|
||||||
|
* Creates an OATH key with the specified parameters
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct oath_key *
|
||||||
|
oath_key_create(const char *label,
|
||||||
|
enum oath_mode mode, enum oath_hash hash,
|
||||||
|
const char *keydata, size_t keylen)
|
||||||
|
{
|
||||||
|
char keybuf[OATH_MAX_KEYLEN];
|
||||||
|
struct oath_key *key;
|
||||||
|
int labellen;
|
||||||
|
|
||||||
|
/* check label */
|
||||||
|
if (label == NULL ||
|
||||||
|
(labellen = strlen(label)) > OATH_MAX_LABELLEN)
|
||||||
|
return (NULL);
|
||||||
|
|
||||||
|
/* check key length */
|
||||||
|
if (keylen > OATH_MAX_KEYLEN ||
|
||||||
|
(keydata != NULL && keylen == 0))
|
||||||
|
return (NULL);
|
||||||
|
if (keylen == 0)
|
||||||
|
keylen = 20;
|
||||||
|
|
||||||
|
/* check mode */
|
||||||
|
switch (mode) {
|
||||||
|
case om_hotp:
|
||||||
|
case om_totp:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check hash */
|
||||||
|
switch (hash) {
|
||||||
|
case oh_undef:
|
||||||
|
hash = oh_sha1;
|
||||||
|
break;
|
||||||
|
case oh_md5:
|
||||||
|
case oh_sha1:
|
||||||
|
case oh_sha256:
|
||||||
|
case oh_sha512:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* generate key data if necessary */
|
||||||
|
if (keydata == NULL) {
|
||||||
|
if (rand_bytes((uint8_t *)keybuf, keylen) != 1)
|
||||||
|
return (NULL);
|
||||||
|
keydata = keybuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* allocate */
|
||||||
|
if ((key = oath_key_alloc()) == NULL)
|
||||||
|
return (NULL);
|
||||||
|
|
||||||
|
/* label */
|
||||||
|
memcpy(key->label, label, labellen);
|
||||||
|
key->label[labellen] = 0;
|
||||||
|
key->labellen = labellen;
|
||||||
|
|
||||||
|
/* mode and hash */
|
||||||
|
key->mode = mode;
|
||||||
|
key->hash = hash;
|
||||||
|
|
||||||
|
/* default parameters */
|
||||||
|
key->digits = 6;
|
||||||
|
if (key->mode == om_totp)
|
||||||
|
key->timestep = 30;
|
||||||
|
|
||||||
|
/* key */
|
||||||
|
memcpy(key->key, keydata, keylen);
|
||||||
|
key->keylen = keylen;
|
||||||
|
|
||||||
|
return (key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The =oath_key_create function allocates and initializes an OATH key
|
||||||
|
* structure with the specified parameters.
|
||||||
|
*
|
||||||
|
* The =label parameter must point to a string describing the key.
|
||||||
|
*
|
||||||
|
* The =mode parameter indicates the OTP algorithm to use:
|
||||||
|
*
|
||||||
|
* ;om_hotp:
|
||||||
|
* RFC 4226 HOTP
|
||||||
|
* ;om_totp:
|
||||||
|
* RFC 6238 TOTP
|
||||||
|
*
|
||||||
|
* The =hash parameter indicates which hash algorithm to use:
|
||||||
|
*
|
||||||
|
* ;oh_md5:
|
||||||
|
* RFC 1321 MD5
|
||||||
|
* ;oh_sha1:
|
||||||
|
* RFC 3174 SHA-1
|
||||||
|
* ;oh_sha256:
|
||||||
|
* RFC 6234 SHA-256
|
||||||
|
* ;oh_sha512:
|
||||||
|
* RFC 6234 SHA-512
|
||||||
|
*
|
||||||
|
* If =hash is ;oh_undef, the default algorithm (SHA-1) is used.
|
||||||
|
*
|
||||||
|
* The =keydata parameter should point to a buffer containing the raw key
|
||||||
|
* to use.
|
||||||
|
* If =keydata is NULL, a key will be randomly generated.
|
||||||
|
* Note that the strength of the generated key is dependent on the
|
||||||
|
* strength of the operating system's pseudo-random number generator.
|
||||||
|
*
|
||||||
|
* The =keylen parameter specifies the length of the provided (or
|
||||||
|
* generated) key in bytes.
|
||||||
|
* Note that some OATH HOTP / TOTP implementations do not support key
|
||||||
|
* lengths that are not a multiple of 20 bits (5 bytes).
|
||||||
|
* If =keydata is NULL and =keylen is 0, a hardcoded default of 160 bits
|
||||||
|
* (20 bytes) is used.
|
||||||
|
*
|
||||||
|
* The following key parameters are set to hardcoded default values and
|
||||||
|
* can be changed after key creation:
|
||||||
|
*
|
||||||
|
* - For HOTP keys, the initial counter value is set to 0.
|
||||||
|
* - For TOTP keys, the timestep is set to 30 seconds.
|
||||||
|
* - For both HOTP and TOTP keys, the number of digits is set to 6.
|
||||||
|
*
|
||||||
|
* Keys created with =oath_key_create must be freed using =oath_key_free.
|
||||||
|
*
|
||||||
|
* >oath_key_alloc
|
||||||
|
* >oath_key_free
|
||||||
|
*
|
||||||
|
* AUTHOR UIO
|
||||||
|
*/
|
78
lib/oath/oath_key_dummy.c
Normal file
78
lib/oath/oath_key_dummy.c
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2013 Universitetet i Oslo
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote
|
||||||
|
* products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Dag-Erling Smørgrav <des@des.no>
|
||||||
|
* Sponsor: the University of Oslo
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "cryb/impl.h"
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <cryb/oath.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* OATH
|
||||||
|
*
|
||||||
|
* Creates a dummy OATH key structure
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct oath_key *
|
||||||
|
oath_key_dummy(enum oath_mode mode, enum oath_hash hash, unsigned int digits)
|
||||||
|
{
|
||||||
|
struct oath_key *key;
|
||||||
|
|
||||||
|
if ((key = oath_key_alloc()) == NULL)
|
||||||
|
return (NULL);
|
||||||
|
key->dummy = 1;
|
||||||
|
key->mode = mode;
|
||||||
|
key->digits = digits;
|
||||||
|
key->counter = 0;
|
||||||
|
key->timestep = 30;
|
||||||
|
key->hash = hash;
|
||||||
|
memcpy(key->label, OATH_DUMMY_LABEL, sizeof OATH_DUMMY_LABEL);
|
||||||
|
key->labellen = sizeof OATH_DUMMY_LABEL - 1;
|
||||||
|
key->keylen = sizeof key->key;
|
||||||
|
return (key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The =oath_key_dummy function allocates and initializes a dummy OATH key
|
||||||
|
* structure.
|
||||||
|
* Authentication attempts using a dummy key will always fail.
|
||||||
|
*
|
||||||
|
* Keys allocated with =oath_key_dummy must be freed using =oath_key_free.
|
||||||
|
*
|
||||||
|
* >oath_key_alloc
|
||||||
|
* >oath_key_free
|
||||||
|
*
|
||||||
|
* AUTHOR UIO
|
||||||
|
*/
|
77
lib/oath/oath_key_free.c
Normal file
77
lib/oath/oath_key_free.c
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2013 Universitetet i Oslo
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote
|
||||||
|
* products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Dag-Erling Smørgrav <des@des.no>
|
||||||
|
* Sponsor: the University of Oslo
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "cryb/impl.h"
|
||||||
|
|
||||||
|
#include <sys/mman.h>
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <cryb/oath.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* OATH
|
||||||
|
*
|
||||||
|
* Wipes and frees an OATH key structure
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
oath_key_free(struct oath_key *key)
|
||||||
|
{
|
||||||
|
int mapped, locked;
|
||||||
|
|
||||||
|
if (key != NULL) {
|
||||||
|
mapped = key->mapped;
|
||||||
|
locked = key->locked;
|
||||||
|
memset(key, 0, sizeof *key);
|
||||||
|
if (mapped) {
|
||||||
|
if (locked)
|
||||||
|
munlock(key, sizeof *key);
|
||||||
|
munmap(key, sizeof *key);
|
||||||
|
} else {
|
||||||
|
free(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The =oath_key_free function wipes and frees an OATH key structure which
|
||||||
|
* was previously allocated using the =oath_key_alloc function.
|
||||||
|
*
|
||||||
|
* >oath_key_alloc
|
||||||
|
*
|
||||||
|
* AUTHOR UIO
|
||||||
|
*/
|
93
lib/oath/oath_key_from_file.c
Normal file
93
lib/oath/oath_key_from_file.c
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2013 Universitetet i Oslo
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote
|
||||||
|
* products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Dag-Erling Smørgrav <des@des.no>
|
||||||
|
* Sponsor: the University of Oslo
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "cryb/impl.h"
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <cryb/oath.h>
|
||||||
|
#include <cryb/strlcmp.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* OATH
|
||||||
|
*
|
||||||
|
* Loads an OATH key from a file
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct oath_key *
|
||||||
|
oath_key_from_file(const char *filename)
|
||||||
|
{
|
||||||
|
struct oath_key *key;
|
||||||
|
FILE *f;
|
||||||
|
char *line;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
if ((f = fopen(filename, "r")) == NULL)
|
||||||
|
return (NULL);
|
||||||
|
/* get first non-empty non-comment line */
|
||||||
|
line = openpam_readline(f, NULL, &len);
|
||||||
|
if (strlcmp("otpauth://", line, len) == 0) {
|
||||||
|
key = oath_key_from_uri(line);
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
openpam_log(PAM_LOG_ERROR,
|
||||||
|
"unrecognized key file format: %s", filename);
|
||||||
|
*/
|
||||||
|
key = NULL;
|
||||||
|
}
|
||||||
|
fclose(f);
|
||||||
|
return (key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The =oath_key_from_file function loads a key from the specified file.
|
||||||
|
* The file format is automatically detected.
|
||||||
|
*
|
||||||
|
* The following key file formats are supported:
|
||||||
|
*
|
||||||
|
* - otpauth URI
|
||||||
|
*
|
||||||
|
* Keys created with =oath_key_from_file must be freed using
|
||||||
|
* =oath_key_free.
|
||||||
|
*
|
||||||
|
* >oath_key_alloc
|
||||||
|
* >oath_key_free
|
||||||
|
* >oath_key_from_uri
|
||||||
|
*
|
||||||
|
* AUTHOR UIO
|
||||||
|
*/
|
221
lib/oath/oath_key_from_uri.c
Normal file
221
lib/oath/oath_key_from_uri.c
Normal file
|
@ -0,0 +1,221 @@
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2013-2014 Universitetet i Oslo
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote
|
||||||
|
* products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Dag-Erling Smørgrav <des@des.no>
|
||||||
|
* Sponsor: the University of Oslo
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "cryb/impl.h"
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <cryb/rfc3986.h>
|
||||||
|
#include <cryb/rfc4648.h>
|
||||||
|
#include <cryb/strlcmp.h>
|
||||||
|
#include <cryb/oath.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* OATH
|
||||||
|
*
|
||||||
|
* Creates an OATH key from a Google otpauth URI
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct oath_key *
|
||||||
|
oath_key_from_uri(const char *uri)
|
||||||
|
{
|
||||||
|
struct oath_key *key;
|
||||||
|
const char *p, *q, *r;
|
||||||
|
uintmax_t n;
|
||||||
|
char *e;
|
||||||
|
|
||||||
|
if ((key = oath_key_alloc()) == NULL)
|
||||||
|
return (NULL);
|
||||||
|
|
||||||
|
/* check method */
|
||||||
|
p = uri;
|
||||||
|
if (strlcmp("otpauth://", p, 10) != 0)
|
||||||
|
goto invalid;
|
||||||
|
p += 10;
|
||||||
|
|
||||||
|
/* check mode (hotp = event, totp = time-sync) */
|
||||||
|
if ((q = strchr(p, '/')) == NULL)
|
||||||
|
goto invalid;
|
||||||
|
if (strlcmp("hotp", p, q - p) == 0) {
|
||||||
|
key->mode = om_hotp;
|
||||||
|
} else if (strlcmp("totp", p, q - p) == 0) {
|
||||||
|
key->mode = om_totp;
|
||||||
|
} else {
|
||||||
|
goto invalid;
|
||||||
|
}
|
||||||
|
p = q + 1;
|
||||||
|
|
||||||
|
/* extract label */
|
||||||
|
if ((q = strchr(p, '?')) == NULL)
|
||||||
|
goto invalid;
|
||||||
|
key->labellen = sizeof key->label;
|
||||||
|
if (percent_decode(p, q - p, key->label, &key->labellen) != 0)
|
||||||
|
goto invalid;
|
||||||
|
p = q + 1;
|
||||||
|
|
||||||
|
/* extract parameters */
|
||||||
|
key->counter = UINT64_MAX;
|
||||||
|
key->lastused = UINT64_MAX;
|
||||||
|
while (*p != '\0') {
|
||||||
|
if ((q = strchr(p, '=')) == NULL)
|
||||||
|
goto invalid;
|
||||||
|
q = q + 1;
|
||||||
|
if ((r = strchr(p, '&')) == NULL)
|
||||||
|
r = strchr(p, '\0');
|
||||||
|
if (r < q)
|
||||||
|
/* & before = */
|
||||||
|
goto invalid;
|
||||||
|
/* p points to key, q points to value, r points to & or NUL */
|
||||||
|
if (strlcmp("secret=", p, q - p) == 0) {
|
||||||
|
if (key->keylen != 0)
|
||||||
|
/* dupe */
|
||||||
|
goto invalid;
|
||||||
|
key->keylen = sizeof key->key;
|
||||||
|
if (base32_decode(q, r - q, key->key, &key->keylen) != 0)
|
||||||
|
goto invalid;
|
||||||
|
} else if (strlcmp("algorithm=", p, q - p) == 0) {
|
||||||
|
if (key->hash != oh_undef)
|
||||||
|
/* dupe */
|
||||||
|
goto invalid;
|
||||||
|
if (strlcmp("SHA1", q, r - q) == 0)
|
||||||
|
key->hash = oh_sha1;
|
||||||
|
else if (strlcmp("SHA256", q, r - q) == 0)
|
||||||
|
key->hash = oh_sha256;
|
||||||
|
else if (strlcmp("SHA512", q, r - q) == 0)
|
||||||
|
key->hash = oh_sha512;
|
||||||
|
else if (strlcmp("MD5", q, r - q) == 0)
|
||||||
|
key->hash = oh_md5;
|
||||||
|
else
|
||||||
|
goto invalid;
|
||||||
|
} else if (strlcmp("digits=", p, q - p) == 0) {
|
||||||
|
if (key->digits != 0)
|
||||||
|
/* dupe */
|
||||||
|
goto invalid;
|
||||||
|
/* only 6 or 8 */
|
||||||
|
if (r - q != 1 || (*q != '6' && *q != '8'))
|
||||||
|
goto invalid;
|
||||||
|
key->digits = *q - '0';
|
||||||
|
} else if (strlcmp("counter=", p, q - p) == 0) {
|
||||||
|
if (key->counter != UINT64_MAX)
|
||||||
|
/* dupe */
|
||||||
|
goto invalid;
|
||||||
|
n = strtoumax(q, &e, 10);
|
||||||
|
if (e != r || n >= UINT64_MAX)
|
||||||
|
goto invalid;
|
||||||
|
key->counter = (uint64_t)n;
|
||||||
|
} else if (strlcmp("lastused=", p, q - p) == 0) {
|
||||||
|
if (key->lastused != UINT64_MAX)
|
||||||
|
/* dupe */
|
||||||
|
goto invalid;
|
||||||
|
n = strtoumax(q, &e, 10);
|
||||||
|
if (e != r || n >= UINT64_MAX)
|
||||||
|
goto invalid;
|
||||||
|
key->lastused = (uint64_t)n;
|
||||||
|
} else if (strlcmp("period=", p, q - p) == 0) {
|
||||||
|
if (key->timestep != 0)
|
||||||
|
/* dupe */
|
||||||
|
goto invalid;
|
||||||
|
n = strtoumax(q, &e, 10);
|
||||||
|
if (e != r || n > OATH_MAX_TIMESTEP)
|
||||||
|
goto invalid;
|
||||||
|
key->timestep = n;
|
||||||
|
} else if (strlcmp("issuer=", p, q - p) == 0) {
|
||||||
|
// noop for now
|
||||||
|
} else {
|
||||||
|
goto invalid;
|
||||||
|
}
|
||||||
|
/* final parameter? */
|
||||||
|
if (*r == '\0')
|
||||||
|
break;
|
||||||
|
/* skip & and continue */
|
||||||
|
p = r + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* sanity checks and default values */
|
||||||
|
if (key->mode == om_hotp) {
|
||||||
|
if (key->counter == UINT64_MAX)
|
||||||
|
key->counter = 0;
|
||||||
|
if (key->timestep != 0)
|
||||||
|
goto invalid;
|
||||||
|
if (key->lastused != UINT64_MAX)
|
||||||
|
goto invalid;
|
||||||
|
} else if (key->mode == om_totp) {
|
||||||
|
if (key->counter != UINT64_MAX)
|
||||||
|
goto invalid;
|
||||||
|
if (key->timestep == 0)
|
||||||
|
key->timestep = OATH_DEF_TIMESTEP;
|
||||||
|
if (key->lastused == UINT64_MAX)
|
||||||
|
key->lastused = 0;
|
||||||
|
} else {
|
||||||
|
/* unreachable */
|
||||||
|
oath_key_free(key);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
if (key->hash == oh_undef)
|
||||||
|
key->hash = oh_sha1;
|
||||||
|
if (key->digits == 0)
|
||||||
|
key->digits = 6;
|
||||||
|
if (key->keylen == 0)
|
||||||
|
goto invalid;
|
||||||
|
return (key);
|
||||||
|
|
||||||
|
invalid:
|
||||||
|
// openpam_log(PAM_LOG_NOTICE, "invalid OATH URI: %s", uri);
|
||||||
|
oath_key_free(key);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The =oath_key_from_uri function parses a Google otpauth URI into a key
|
||||||
|
* structure.
|
||||||
|
*
|
||||||
|
* The =uri parameter points to a NUL-terminated string containing the
|
||||||
|
* URI.
|
||||||
|
*
|
||||||
|
* Keys created with =oath_key_from_uri must be freed using
|
||||||
|
* =oath_key_free.
|
||||||
|
*
|
||||||
|
* >oath_key_alloc
|
||||||
|
* >oath_key_free
|
||||||
|
* >oath_key_to_uri
|
||||||
|
*
|
||||||
|
* REFERENCES
|
||||||
|
*
|
||||||
|
* https://code.google.com/p/google-authenticator/wiki/KeyUriFormat
|
||||||
|
*
|
||||||
|
* AUTHOR UIO
|
||||||
|
*/
|
101
lib/oath/oath_totp.c
Normal file
101
lib/oath/oath_totp.c
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2012-2013 Universitetet i Oslo
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote
|
||||||
|
* products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Dag-Erling Smørgrav <des@des.no>
|
||||||
|
* Sponsor: the University of Oslo
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "cryb/impl.h"
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#include <cryb/oath.h>
|
||||||
|
|
||||||
|
#define TOTP_TIME_STEP 30
|
||||||
|
|
||||||
|
unsigned int
|
||||||
|
oath_totp(const uint8_t *K, size_t Klen, unsigned int Digit)
|
||||||
|
{
|
||||||
|
time_t now;
|
||||||
|
|
||||||
|
time(&now);
|
||||||
|
return (oath_hotp(K, Klen, now / TOTP_TIME_STEP, Digit));
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int
|
||||||
|
oath_totp_current(const struct oath_key *k)
|
||||||
|
{
|
||||||
|
unsigned int code;
|
||||||
|
uint64_t seq;
|
||||||
|
|
||||||
|
if (k == NULL)
|
||||||
|
return (-1);
|
||||||
|
if (k->mode != om_totp)
|
||||||
|
return (-1);
|
||||||
|
if (k->timestep == 0)
|
||||||
|
return (-1);
|
||||||
|
seq = time(NULL) / k->timestep;
|
||||||
|
code = oath_hotp(k->key, k->keylen, seq, k->digits);
|
||||||
|
return (code);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Compares the code provided by the user with expected values within a
|
||||||
|
* given window. Returns 1 if there was a match, 0 if not, and -1 if an
|
||||||
|
* error occurred.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
oath_totp_match(struct oath_key *k, unsigned int response, int window)
|
||||||
|
{
|
||||||
|
unsigned int code;
|
||||||
|
uint64_t seq;
|
||||||
|
|
||||||
|
if (k == NULL)
|
||||||
|
return (-1);
|
||||||
|
if (window < 1)
|
||||||
|
return (-1);
|
||||||
|
if (k->mode != om_totp)
|
||||||
|
return (-1);
|
||||||
|
if (k->timestep == 0)
|
||||||
|
return (-1);
|
||||||
|
seq = time(NULL) / k->timestep;
|
||||||
|
for (int i = -window; i <= window; ++i) {
|
||||||
|
if (seq + i <= k->lastused)
|
||||||
|
continue;
|
||||||
|
code = oath_hotp(k->key, k->keylen, seq + i, k->digits);
|
||||||
|
if (code == response && !k->dummy) {
|
||||||
|
k->lastused = seq;
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (0);
|
||||||
|
}
|
10
lib/rand/Makefile.am
Normal file
10
lib/rand/Makefile.am
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
# $Id$
|
||||||
|
|
||||||
|
AM_CPPFLAGS = -I$(top_srcdir)/include
|
||||||
|
|
||||||
|
lib_LTLIBRARIES = libcryb-rand.la
|
||||||
|
|
||||||
|
libcryb_rand_la_SOURCES = cryb_rand.c
|
||||||
|
|
||||||
|
libcryb_rand_la_LIBADD = \
|
||||||
|
$(top_builddir)/lib/core/libcryb-core.la
|
64
lib/rand/cryb_rand.c
Normal file
64
lib/rand/cryb_rand.c
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2014 Dag-Erling Smørgrav
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote
|
||||||
|
* products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Dag-Erling Smørgrav <des@des.no>
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "cryb/impl.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <cryb/rand.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
rand_bytes(uint8_t *buf, size_t len)
|
||||||
|
{
|
||||||
|
ssize_t rlen;
|
||||||
|
int fd, serrno;
|
||||||
|
|
||||||
|
if ((fd = open("/dev/random", O_RDONLY)) < 0)
|
||||||
|
return (-1);
|
||||||
|
if ((rlen = read(fd, buf, len)) < 0) {
|
||||||
|
serrno = errno;
|
||||||
|
close(fd);
|
||||||
|
errno = serrno;
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
close(fd);
|
||||||
|
if (rlen != (ssize_t)len) {
|
||||||
|
errno = EIO;
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
return (0);
|
||||||
|
}
|
21
lib/rsaref/Makefile.am
Normal file
21
lib/rsaref/Makefile.am
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
# $Id$
|
||||||
|
|
||||||
|
AM_CPPFLAGS = -include $(top_srcdir)/include/cryb/nocoverage.h
|
||||||
|
|
||||||
|
noinst_LTLIBRARIES = librsaref.la
|
||||||
|
|
||||||
|
librsaref_la_SOURCES = \
|
||||||
|
desc.c \
|
||||||
|
digit.c \
|
||||||
|
md2c.c \
|
||||||
|
md5c.c \
|
||||||
|
nn.c \
|
||||||
|
prime.c \
|
||||||
|
r_dh.c \
|
||||||
|
r_encode.c \
|
||||||
|
r_enhanc.c \
|
||||||
|
r_keygen.c \
|
||||||
|
r_random.c \
|
||||||
|
r_stdlib.c \
|
||||||
|
rsa.c
|
||||||
|
librsaref_la_CFLAGS = -DPROTOTYPES=1
|
56
lib/rsaref/des.h
Normal file
56
lib/rsaref/des.h
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
/* DES.H - header file for DESC.C
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _DES_H_
|
||||||
|
#define _DES_H_ 1
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
UINT4 subkeys[32]; /* subkeys */
|
||||||
|
UINT4 iv[2]; /* initializing vector */
|
||||||
|
UINT4 originalIV[2]; /* for restarting the context */
|
||||||
|
int encrypt; /* encrypt flag */
|
||||||
|
} DES_CBC_CTX;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
UINT4 subkeys[32]; /* subkeys */
|
||||||
|
UINT4 iv[2]; /* initializing vector */
|
||||||
|
UINT4 inputWhitener[2]; /* input whitener */
|
||||||
|
UINT4 outputWhitener[2]; /* output whitener */
|
||||||
|
UINT4 originalIV[2]; /* for restarting the context */
|
||||||
|
int encrypt; /* encrypt flag */
|
||||||
|
} DESX_CBC_CTX;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
UINT4 subkeys[3][32]; /* subkeys for three operations */
|
||||||
|
UINT4 iv[2]; /* initializing vector */
|
||||||
|
UINT4 originalIV[2]; /* for restarting the context */
|
||||||
|
int encrypt; /* encrypt flag */
|
||||||
|
} DES3_CBC_CTX;
|
||||||
|
|
||||||
|
void DES_CBCInit PROTO_LIST
|
||||||
|
((DES_CBC_CTX *, unsigned char *, unsigned char *, int));
|
||||||
|
int DES_CBCUpdate PROTO_LIST
|
||||||
|
((DES_CBC_CTX *, unsigned char *, unsigned char *, unsigned int));
|
||||||
|
void DES_CBCRestart PROTO_LIST ((DES_CBC_CTX *));
|
||||||
|
|
||||||
|
void DESX_CBCInit PROTO_LIST
|
||||||
|
((DESX_CBC_CTX *, unsigned char *, unsigned char *, int));
|
||||||
|
int DESX_CBCUpdate PROTO_LIST
|
||||||
|
((DESX_CBC_CTX *, unsigned char *, unsigned char *, unsigned int));
|
||||||
|
void DESX_CBCRestart PROTO_LIST ((DESX_CBC_CTX *));
|
||||||
|
|
||||||
|
void DES3_CBCInit PROTO_LIST
|
||||||
|
((DES3_CBC_CTX *, unsigned char *, unsigned char *, int));
|
||||||
|
int DES3_CBCUpdate PROTO_LIST
|
||||||
|
((DES3_CBC_CTX *, unsigned char *, unsigned char *, unsigned int));
|
||||||
|
void DES3_CBCRestart PROTO_LIST ((DES3_CBC_CTX *));
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
645
lib/rsaref/desc.c
Normal file
645
lib/rsaref/desc.c
Normal file
|
@ -0,0 +1,645 @@
|
||||||
|
/* DESC.C - Data Encryption Standard routines for RSAREF
|
||||||
|
Based on "Karn/Hoey/Outerbridge" implementation (KHODES)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "global.h"
|
||||||
|
#include "rsaref.h"
|
||||||
|
#include "des.h"
|
||||||
|
|
||||||
|
static UINT2 BYTE_BIT[8] = {
|
||||||
|
0200, 0100, 040, 020, 010, 04, 02, 01
|
||||||
|
};
|
||||||
|
|
||||||
|
static UINT4 BIG_BYTE[24] = {
|
||||||
|
0x800000L, 0x400000L, 0x200000L, 0x100000L,
|
||||||
|
0x80000L, 0x40000L, 0x20000L, 0x10000L,
|
||||||
|
0x8000L, 0x4000L, 0x2000L, 0x1000L,
|
||||||
|
0x800L, 0x400L, 0x200L, 0x100L,
|
||||||
|
0x80L, 0x40L, 0x20L, 0x10L,
|
||||||
|
0x8L, 0x4L, 0x2L, 0x1L
|
||||||
|
};
|
||||||
|
|
||||||
|
static unsigned char PC1[56] = {
|
||||||
|
56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17,
|
||||||
|
9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35,
|
||||||
|
62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21,
|
||||||
|
13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3
|
||||||
|
};
|
||||||
|
|
||||||
|
static unsigned char TOTAL_ROTATIONS[16] = {
|
||||||
|
1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28
|
||||||
|
};
|
||||||
|
|
||||||
|
static unsigned char PC2[48] = {
|
||||||
|
13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9,
|
||||||
|
22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1,
|
||||||
|
40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47,
|
||||||
|
43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31
|
||||||
|
};
|
||||||
|
|
||||||
|
static UINT4 SP1[64] = {
|
||||||
|
0x01010400L, 0x00000000L, 0x00010000L, 0x01010404L,
|
||||||
|
0x01010004L, 0x00010404L, 0x00000004L, 0x00010000L,
|
||||||
|
0x00000400L, 0x01010400L, 0x01010404L, 0x00000400L,
|
||||||
|
0x01000404L, 0x01010004L, 0x01000000L, 0x00000004L,
|
||||||
|
0x00000404L, 0x01000400L, 0x01000400L, 0x00010400L,
|
||||||
|
0x00010400L, 0x01010000L, 0x01010000L, 0x01000404L,
|
||||||
|
0x00010004L, 0x01000004L, 0x01000004L, 0x00010004L,
|
||||||
|
0x00000000L, 0x00000404L, 0x00010404L, 0x01000000L,
|
||||||
|
0x00010000L, 0x01010404L, 0x00000004L, 0x01010000L,
|
||||||
|
0x01010400L, 0x01000000L, 0x01000000L, 0x00000400L,
|
||||||
|
0x01010004L, 0x00010000L, 0x00010400L, 0x01000004L,
|
||||||
|
0x00000400L, 0x00000004L, 0x01000404L, 0x00010404L,
|
||||||
|
0x01010404L, 0x00010004L, 0x01010000L, 0x01000404L,
|
||||||
|
0x01000004L, 0x00000404L, 0x00010404L, 0x01010400L,
|
||||||
|
0x00000404L, 0x01000400L, 0x01000400L, 0x00000000L,
|
||||||
|
0x00010004L, 0x00010400L, 0x00000000L, 0x01010004L
|
||||||
|
};
|
||||||
|
|
||||||
|
static UINT4 SP2[64] = {
|
||||||
|
0x80108020L, 0x80008000L, 0x00008000L, 0x00108020L,
|
||||||
|
0x00100000L, 0x00000020L, 0x80100020L, 0x80008020L,
|
||||||
|
0x80000020L, 0x80108020L, 0x80108000L, 0x80000000L,
|
||||||
|
0x80008000L, 0x00100000L, 0x00000020L, 0x80100020L,
|
||||||
|
0x00108000L, 0x00100020L, 0x80008020L, 0x00000000L,
|
||||||
|
0x80000000L, 0x00008000L, 0x00108020L, 0x80100000L,
|
||||||
|
0x00100020L, 0x80000020L, 0x00000000L, 0x00108000L,
|
||||||
|
0x00008020L, 0x80108000L, 0x80100000L, 0x00008020L,
|
||||||
|
0x00000000L, 0x00108020L, 0x80100020L, 0x00100000L,
|
||||||
|
0x80008020L, 0x80100000L, 0x80108000L, 0x00008000L,
|
||||||
|
0x80100000L, 0x80008000L, 0x00000020L, 0x80108020L,
|
||||||
|
0x00108020L, 0x00000020L, 0x00008000L, 0x80000000L,
|
||||||
|
0x00008020L, 0x80108000L, 0x00100000L, 0x80000020L,
|
||||||
|
0x00100020L, 0x80008020L, 0x80000020L, 0x00100020L,
|
||||||
|
0x00108000L, 0x00000000L, 0x80008000L, 0x00008020L,
|
||||||
|
0x80000000L, 0x80100020L, 0x80108020L, 0x00108000L
|
||||||
|
};
|
||||||
|
|
||||||
|
static UINT4 SP3[64] = {
|
||||||
|
0x00000208L, 0x08020200L, 0x00000000L, 0x08020008L,
|
||||||
|
0x08000200L, 0x00000000L, 0x00020208L, 0x08000200L,
|
||||||
|
0x00020008L, 0x08000008L, 0x08000008L, 0x00020000L,
|
||||||
|
0x08020208L, 0x00020008L, 0x08020000L, 0x00000208L,
|
||||||
|
0x08000000L, 0x00000008L, 0x08020200L, 0x00000200L,
|
||||||
|
0x00020200L, 0x08020000L, 0x08020008L, 0x00020208L,
|
||||||
|
0x08000208L, 0x00020200L, 0x00020000L, 0x08000208L,
|
||||||
|
0x00000008L, 0x08020208L, 0x00000200L, 0x08000000L,
|
||||||
|
0x08020200L, 0x08000000L, 0x00020008L, 0x00000208L,
|
||||||
|
0x00020000L, 0x08020200L, 0x08000200L, 0x00000000L,
|
||||||
|
0x00000200L, 0x00020008L, 0x08020208L, 0x08000200L,
|
||||||
|
0x08000008L, 0x00000200L, 0x00000000L, 0x08020008L,
|
||||||
|
0x08000208L, 0x00020000L, 0x08000000L, 0x08020208L,
|
||||||
|
0x00000008L, 0x00020208L, 0x00020200L, 0x08000008L,
|
||||||
|
0x08020000L, 0x08000208L, 0x00000208L, 0x08020000L,
|
||||||
|
0x00020208L, 0x00000008L, 0x08020008L, 0x00020200L
|
||||||
|
};
|
||||||
|
|
||||||
|
static UINT4 SP4[64] = {
|
||||||
|
0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L,
|
||||||
|
0x00802080L, 0x00800081L, 0x00800001L, 0x00002001L,
|
||||||
|
0x00000000L, 0x00802000L, 0x00802000L, 0x00802081L,
|
||||||
|
0x00000081L, 0x00000000L, 0x00800080L, 0x00800001L,
|
||||||
|
0x00000001L, 0x00002000L, 0x00800000L, 0x00802001L,
|
||||||
|
0x00000080L, 0x00800000L, 0x00002001L, 0x00002080L,
|
||||||
|
0x00800081L, 0x00000001L, 0x00002080L, 0x00800080L,
|
||||||
|
0x00002000L, 0x00802080L, 0x00802081L, 0x00000081L,
|
||||||
|
0x00800080L, 0x00800001L, 0x00802000L, 0x00802081L,
|
||||||
|
0x00000081L, 0x00000000L, 0x00000000L, 0x00802000L,
|
||||||
|
0x00002080L, 0x00800080L, 0x00800081L, 0x00000001L,
|
||||||
|
0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L,
|
||||||
|
0x00802081L, 0x00000081L, 0x00000001L, 0x00002000L,
|
||||||
|
0x00800001L, 0x00002001L, 0x00802080L, 0x00800081L,
|
||||||
|
0x00002001L, 0x00002080L, 0x00800000L, 0x00802001L,
|
||||||
|
0x00000080L, 0x00800000L, 0x00002000L, 0x00802080L
|
||||||
|
};
|
||||||
|
|
||||||
|
static UINT4 SP5[64] = {
|
||||||
|
0x00000100L, 0x02080100L, 0x02080000L, 0x42000100L,
|
||||||
|
0x00080000L, 0x00000100L, 0x40000000L, 0x02080000L,
|
||||||
|
0x40080100L, 0x00080000L, 0x02000100L, 0x40080100L,
|
||||||
|
0x42000100L, 0x42080000L, 0x00080100L, 0x40000000L,
|
||||||
|
0x02000000L, 0x40080000L, 0x40080000L, 0x00000000L,
|
||||||
|
0x40000100L, 0x42080100L, 0x42080100L, 0x02000100L,
|
||||||
|
0x42080000L, 0x40000100L, 0x00000000L, 0x42000000L,
|
||||||
|
0x02080100L, 0x02000000L, 0x42000000L, 0x00080100L,
|
||||||
|
0x00080000L, 0x42000100L, 0x00000100L, 0x02000000L,
|
||||||
|
0x40000000L, 0x02080000L, 0x42000100L, 0x40080100L,
|
||||||
|
0x02000100L, 0x40000000L, 0x42080000L, 0x02080100L,
|
||||||
|
0x40080100L, 0x00000100L, 0x02000000L, 0x42080000L,
|
||||||
|
0x42080100L, 0x00080100L, 0x42000000L, 0x42080100L,
|
||||||
|
0x02080000L, 0x00000000L, 0x40080000L, 0x42000000L,
|
||||||
|
0x00080100L, 0x02000100L, 0x40000100L, 0x00080000L,
|
||||||
|
0x00000000L, 0x40080000L, 0x02080100L, 0x40000100L
|
||||||
|
};
|
||||||
|
|
||||||
|
static UINT4 SP6[64] = {
|
||||||
|
0x20000010L, 0x20400000L, 0x00004000L, 0x20404010L,
|
||||||
|
0x20400000L, 0x00000010L, 0x20404010L, 0x00400000L,
|
||||||
|
0x20004000L, 0x00404010L, 0x00400000L, 0x20000010L,
|
||||||
|
0x00400010L, 0x20004000L, 0x20000000L, 0x00004010L,
|
||||||
|
0x00000000L, 0x00400010L, 0x20004010L, 0x00004000L,
|
||||||
|
0x00404000L, 0x20004010L, 0x00000010L, 0x20400010L,
|
||||||
|
0x20400010L, 0x00000000L, 0x00404010L, 0x20404000L,
|
||||||
|
0x00004010L, 0x00404000L, 0x20404000L, 0x20000000L,
|
||||||
|
0x20004000L, 0x00000010L, 0x20400010L, 0x00404000L,
|
||||||
|
0x20404010L, 0x00400000L, 0x00004010L, 0x20000010L,
|
||||||
|
0x00400000L, 0x20004000L, 0x20000000L, 0x00004010L,
|
||||||
|
0x20000010L, 0x20404010L, 0x00404000L, 0x20400000L,
|
||||||
|
0x00404010L, 0x20404000L, 0x00000000L, 0x20400010L,
|
||||||
|
0x00000010L, 0x00004000L, 0x20400000L, 0x00404010L,
|
||||||
|
0x00004000L, 0x00400010L, 0x20004010L, 0x00000000L,
|
||||||
|
0x20404000L, 0x20000000L, 0x00400010L, 0x20004010L
|
||||||
|
};
|
||||||
|
|
||||||
|
static UINT4 SP7[64] = {
|
||||||
|
0x00200000L, 0x04200002L, 0x04000802L, 0x00000000L,
|
||||||
|
0x00000800L, 0x04000802L, 0x00200802L, 0x04200800L,
|
||||||
|
0x04200802L, 0x00200000L, 0x00000000L, 0x04000002L,
|
||||||
|
0x00000002L, 0x04000000L, 0x04200002L, 0x00000802L,
|
||||||
|
0x04000800L, 0x00200802L, 0x00200002L, 0x04000800L,
|
||||||
|
0x04000002L, 0x04200000L, 0x04200800L, 0x00200002L,
|
||||||
|
0x04200000L, 0x00000800L, 0x00000802L, 0x04200802L,
|
||||||
|
0x00200800L, 0x00000002L, 0x04000000L, 0x00200800L,
|
||||||
|
0x04000000L, 0x00200800L, 0x00200000L, 0x04000802L,
|
||||||
|
0x04000802L, 0x04200002L, 0x04200002L, 0x00000002L,
|
||||||
|
0x00200002L, 0x04000000L, 0x04000800L, 0x00200000L,
|
||||||
|
0x04200800L, 0x00000802L, 0x00200802L, 0x04200800L,
|
||||||
|
0x00000802L, 0x04000002L, 0x04200802L, 0x04200000L,
|
||||||
|
0x00200800L, 0x00000000L, 0x00000002L, 0x04200802L,
|
||||||
|
0x00000000L, 0x00200802L, 0x04200000L, 0x00000800L,
|
||||||
|
0x04000002L, 0x04000800L, 0x00000800L, 0x00200002L
|
||||||
|
};
|
||||||
|
|
||||||
|
static UINT4 SP8[64] = {
|
||||||
|
0x10001040L, 0x00001000L, 0x00040000L, 0x10041040L,
|
||||||
|
0x10000000L, 0x10001040L, 0x00000040L, 0x10000000L,
|
||||||
|
0x00040040L, 0x10040000L, 0x10041040L, 0x00041000L,
|
||||||
|
0x10041000L, 0x00041040L, 0x00001000L, 0x00000040L,
|
||||||
|
0x10040000L, 0x10000040L, 0x10001000L, 0x00001040L,
|
||||||
|
0x00041000L, 0x00040040L, 0x10040040L, 0x10041000L,
|
||||||
|
0x00001040L, 0x00000000L, 0x00000000L, 0x10040040L,
|
||||||
|
0x10000040L, 0x10001000L, 0x00041040L, 0x00040000L,
|
||||||
|
0x00041040L, 0x00040000L, 0x10041000L, 0x00001000L,
|
||||||
|
0x00000040L, 0x10040040L, 0x00001000L, 0x00041040L,
|
||||||
|
0x10001000L, 0x00000040L, 0x10000040L, 0x10040000L,
|
||||||
|
0x10040040L, 0x10000000L, 0x00040000L, 0x10001040L,
|
||||||
|
0x00000000L, 0x10041040L, 0x00040040L, 0x10000040L,
|
||||||
|
0x10040000L, 0x10001000L, 0x10001040L, 0x00000000L,
|
||||||
|
0x10041040L, 0x00041000L, 0x00041000L, 0x00001040L,
|
||||||
|
0x00001040L, 0x00040040L, 0x10000000L, 0x10041000L
|
||||||
|
};
|
||||||
|
|
||||||
|
static void Unpack PROTO_LIST ((unsigned char *, UINT4 *));
|
||||||
|
static void Pack PROTO_LIST ((UINT4 *, unsigned char *));
|
||||||
|
static void DESKey PROTO_LIST ((UINT4 *, unsigned char *, int));
|
||||||
|
static void CookKey PROTO_LIST ((UINT4 *, UINT4 *, int));
|
||||||
|
static void DESFunction PROTO_LIST ((UINT4 *, UINT4 *));
|
||||||
|
|
||||||
|
/* Initialize context. Caller must zeroize the context when finished.
|
||||||
|
*/
|
||||||
|
void DES_CBCInit (context, key, iv, encrypt)
|
||||||
|
DES_CBC_CTX *context; /* context */
|
||||||
|
unsigned char key[8]; /* key */
|
||||||
|
unsigned char iv[8]; /* initializing vector */
|
||||||
|
int encrypt; /* encrypt flag (1 = encrypt, 0 = decrypt) */
|
||||||
|
{
|
||||||
|
/* Copy encrypt flag to context.
|
||||||
|
*/
|
||||||
|
context->encrypt = encrypt;
|
||||||
|
|
||||||
|
/* Pack initializing vector into context.
|
||||||
|
*/
|
||||||
|
Pack (context->iv, iv);
|
||||||
|
|
||||||
|
/* Save the IV for use in Restart */
|
||||||
|
context->originalIV[0] = context->iv[0];
|
||||||
|
context->originalIV[1] = context->iv[1];
|
||||||
|
|
||||||
|
/* Precompute key schedule
|
||||||
|
*/
|
||||||
|
DESKey (context->subkeys, key, encrypt);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* DES-CBC block update operation. Continues a DES-CBC encryption
|
||||||
|
operation, processing eight-byte message blocks, and updating
|
||||||
|
the context.
|
||||||
|
*/
|
||||||
|
int DES_CBCUpdate (context, output, input, len)
|
||||||
|
DES_CBC_CTX *context; /* context */
|
||||||
|
unsigned char *output; /* output block */
|
||||||
|
unsigned char *input; /* input block */
|
||||||
|
unsigned int len; /* length of input and output blocks */
|
||||||
|
{
|
||||||
|
UINT4 inputBlock[2], work[2];
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
if (len % 8)
|
||||||
|
return (RE_LEN);
|
||||||
|
|
||||||
|
for (i = 0; i < len/8; i++) {
|
||||||
|
Pack (inputBlock, &input[8*i]);
|
||||||
|
|
||||||
|
/* Chain if encrypting.
|
||||||
|
*/
|
||||||
|
if (context->encrypt) {
|
||||||
|
work[0] = inputBlock[0] ^ context->iv[0];
|
||||||
|
work[1] = inputBlock[1] ^ context->iv[1];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
work[0] = inputBlock[0];
|
||||||
|
work[1] = inputBlock[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
DESFunction (work, context->subkeys);
|
||||||
|
|
||||||
|
/* Chain if decrypting, then update IV.
|
||||||
|
*/
|
||||||
|
if (context->encrypt) {
|
||||||
|
context->iv[0] = work[0];
|
||||||
|
context->iv[1] = work[1];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
work[0] ^= context->iv[0];
|
||||||
|
work[1] ^= context->iv[1];
|
||||||
|
context->iv[0] = inputBlock[0];
|
||||||
|
context->iv[1] = inputBlock[1];
|
||||||
|
}
|
||||||
|
Unpack (&output[8*i], work);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Zeroize sensitive information.
|
||||||
|
*/
|
||||||
|
R_memset ((POINTER)inputBlock, 0, sizeof (inputBlock));
|
||||||
|
R_memset ((POINTER)work, 0, sizeof (work));
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DES_CBCRestart (context)
|
||||||
|
DES_CBC_CTX *context;
|
||||||
|
{
|
||||||
|
/* Reset to the original IV */
|
||||||
|
context->iv[0] = context->originalIV[0];
|
||||||
|
context->iv[1] = context->originalIV[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize context. Caller must zeroize the context when finished.
|
||||||
|
The key has the DES key, input whitener and output whitener concatenated.
|
||||||
|
*/
|
||||||
|
void DESX_CBCInit (context, key, iv, encrypt)
|
||||||
|
DESX_CBC_CTX *context;
|
||||||
|
unsigned char key[24]; /* DES key and whiteners */
|
||||||
|
unsigned char iv[8]; /* DES initializing vector */
|
||||||
|
int encrypt; /* encrypt flag (1 = encrypt, 0 = decrypt) */
|
||||||
|
{
|
||||||
|
/* Copy encrypt flag to context.
|
||||||
|
*/
|
||||||
|
context->encrypt = encrypt;
|
||||||
|
|
||||||
|
/* Pack initializing vector and whiteners into context.
|
||||||
|
*/
|
||||||
|
Pack (context->iv, iv);
|
||||||
|
Pack (context->inputWhitener, key + 8);
|
||||||
|
Pack (context->outputWhitener, key + 16);
|
||||||
|
|
||||||
|
/* Save the IV for use in Restart */
|
||||||
|
context->originalIV[0] = context->iv[0];
|
||||||
|
context->originalIV[1] = context->iv[1];
|
||||||
|
|
||||||
|
/* Precompute key schedule.
|
||||||
|
*/
|
||||||
|
DESKey (context->subkeys, key, encrypt);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* DESX-CBC block update operation. Continues a DESX-CBC encryption
|
||||||
|
operation, processing eight-byte message blocks, and updating
|
||||||
|
the context.
|
||||||
|
*/
|
||||||
|
int DESX_CBCUpdate (context, output, input, len)
|
||||||
|
DESX_CBC_CTX *context; /* context */
|
||||||
|
unsigned char *output; /* output block */
|
||||||
|
unsigned char *input; /* input block */
|
||||||
|
unsigned int len; /* length of input and output blocks */
|
||||||
|
{
|
||||||
|
UINT4 inputBlock[2], work[2];
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
if (len % 8)
|
||||||
|
return (RE_LEN);
|
||||||
|
|
||||||
|
for (i = 0; i < len/8; i++) {
|
||||||
|
Pack (inputBlock, &input[8*i]);
|
||||||
|
|
||||||
|
/* Chain if encrypting, and xor with whitener.
|
||||||
|
*/
|
||||||
|
if (context->encrypt) {
|
||||||
|
work[0] =
|
||||||
|
inputBlock[0] ^ context->iv[0] ^ context->inputWhitener[0];
|
||||||
|
work[1] =
|
||||||
|
inputBlock[1] ^ context->iv[1] ^ context->inputWhitener[1];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
work[0] = inputBlock[0] ^ context->outputWhitener[0];
|
||||||
|
work[1] = inputBlock[1] ^ context->outputWhitener[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
DESFunction (work, context->subkeys);
|
||||||
|
|
||||||
|
/* Xor with whitener, chain if decrypting, then update IV.
|
||||||
|
*/
|
||||||
|
if (context->encrypt) {
|
||||||
|
work[0] ^= context->outputWhitener[0];
|
||||||
|
work[1] ^= context->outputWhitener[1];
|
||||||
|
context->iv[0] = work[0];
|
||||||
|
context->iv[1] = work[1];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
work[0] ^= context->iv[0] ^ context->inputWhitener[0];
|
||||||
|
work[1] ^= context->iv[1] ^ context->inputWhitener[1];
|
||||||
|
context->iv[0] = inputBlock[0];
|
||||||
|
context->iv[1] = inputBlock[1];
|
||||||
|
}
|
||||||
|
Unpack (&output[8*i], work);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Zeroize sensitive information.
|
||||||
|
*/
|
||||||
|
R_memset ((POINTER)inputBlock, 0, sizeof (inputBlock));
|
||||||
|
R_memset ((POINTER)work, 0, sizeof (work));
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DESX_CBCRestart (context)
|
||||||
|
DESX_CBC_CTX *context;
|
||||||
|
{
|
||||||
|
/* Reset to the original IV */
|
||||||
|
context->iv[0] = context->originalIV[0];
|
||||||
|
context->iv[1] = context->originalIV[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize context. Caller must zeroize the context when finished.
|
||||||
|
*/
|
||||||
|
void DES3_CBCInit(context, key, iv, encrypt)
|
||||||
|
DES3_CBC_CTX *context; /* context */
|
||||||
|
unsigned char key[24]; /* key */
|
||||||
|
unsigned char iv[8]; /* initializing vector */
|
||||||
|
int encrypt; /* encrypt flag (1 = encrypt, 0 = decrypt) */
|
||||||
|
{
|
||||||
|
/* Copy encrypt flag to context.
|
||||||
|
*/
|
||||||
|
context->encrypt = encrypt;
|
||||||
|
|
||||||
|
/* Pack initializing vector into context.
|
||||||
|
*/
|
||||||
|
Pack (context->iv, iv);
|
||||||
|
|
||||||
|
/* Save the IV for use in Restart */
|
||||||
|
context->originalIV[0] = context->iv[0];
|
||||||
|
context->originalIV[1] = context->iv[1];
|
||||||
|
|
||||||
|
/* Precompute key schedules.
|
||||||
|
*/
|
||||||
|
DESKey (context->subkeys[0], encrypt ? key : &key[16], encrypt);
|
||||||
|
DESKey (context->subkeys[1], &key[8], !encrypt);
|
||||||
|
DESKey (context->subkeys[2], encrypt ? &key[16] : key, encrypt);
|
||||||
|
}
|
||||||
|
|
||||||
|
int DES3_CBCUpdate (context, output, input, len)
|
||||||
|
DES3_CBC_CTX *context; /* context */
|
||||||
|
unsigned char *output; /* output block */
|
||||||
|
unsigned char *input; /* input block */
|
||||||
|
unsigned int len; /* length of input and output blocks */
|
||||||
|
{
|
||||||
|
UINT4 inputBlock[2], work[2];
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
if (len % 8)
|
||||||
|
return (RE_LEN);
|
||||||
|
|
||||||
|
for (i = 0; i < len/8; i++) {
|
||||||
|
Pack (inputBlock, &input[8*i]);
|
||||||
|
|
||||||
|
/* Chain if encrypting.
|
||||||
|
*/
|
||||||
|
if (context->encrypt) {
|
||||||
|
work[0] = inputBlock[0] ^ context->iv[0];
|
||||||
|
work[1] = inputBlock[1] ^ context->iv[1];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
work[0] = inputBlock[0];
|
||||||
|
work[1] = inputBlock[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
DESFunction (work, context->subkeys[0]);
|
||||||
|
DESFunction (work, context->subkeys[1]);
|
||||||
|
DESFunction (work, context->subkeys[2]);
|
||||||
|
|
||||||
|
/* Chain if decrypting, then update IV.
|
||||||
|
*/
|
||||||
|
if (context->encrypt) {
|
||||||
|
context->iv[0] = work[0];
|
||||||
|
context->iv[1] = work[1];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
work[0] ^= context->iv[0];
|
||||||
|
work[1] ^= context->iv[1];
|
||||||
|
context->iv[0] = inputBlock[0];
|
||||||
|
context->iv[1] = inputBlock[1];
|
||||||
|
}
|
||||||
|
Unpack (&output[8*i], work);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Zeroize sensitive information.
|
||||||
|
*/
|
||||||
|
R_memset ((POINTER)inputBlock, 0, sizeof (inputBlock));
|
||||||
|
R_memset ((POINTER)work, 0, sizeof (work));
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DES3_CBCRestart (context)
|
||||||
|
DES3_CBC_CTX *context;
|
||||||
|
{
|
||||||
|
/* Reset to the original IV */
|
||||||
|
context->iv[0] = context->originalIV[0];
|
||||||
|
context->iv[1] = context->originalIV[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Pack (into, outof)
|
||||||
|
UINT4 *into;
|
||||||
|
unsigned char *outof;
|
||||||
|
{
|
||||||
|
*into = (*outof++ & 0xffL) << 24;
|
||||||
|
*into |= (*outof++ & 0xffL) << 16;
|
||||||
|
*into |= (*outof++ & 0xffL) << 8;
|
||||||
|
*into++ |= (*outof++ & 0xffL);
|
||||||
|
*into = (*outof++ & 0xffL) << 24;
|
||||||
|
*into |= (*outof++ & 0xffL) << 16;
|
||||||
|
*into |= (*outof++ & 0xffL) << 8;
|
||||||
|
*into |= (*outof & 0xffL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Unpack (into, outof)
|
||||||
|
unsigned char *into;
|
||||||
|
UINT4 *outof;
|
||||||
|
{
|
||||||
|
*into++ = (unsigned char)((*outof >> 24) & 0xffL);
|
||||||
|
*into++ = (unsigned char)((*outof >> 16) & 0xffL);
|
||||||
|
*into++ = (unsigned char)((*outof >> 8) & 0xffL);
|
||||||
|
*into++ = (unsigned char)( *outof++ & 0xffL);
|
||||||
|
*into++ = (unsigned char)((*outof >> 24) & 0xffL);
|
||||||
|
*into++ = (unsigned char)((*outof >> 16) & 0xffL);
|
||||||
|
*into++ = (unsigned char)((*outof >> 8) & 0xffL);
|
||||||
|
*into = (unsigned char)( *outof & 0xffL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DESKey (subkeys, key, encrypt)
|
||||||
|
UINT4 subkeys[32];
|
||||||
|
unsigned char key[8];
|
||||||
|
int encrypt;
|
||||||
|
{
|
||||||
|
UINT4 kn[32];
|
||||||
|
int i, j, l, m, n;
|
||||||
|
unsigned char pc1m[56], pcr[56];
|
||||||
|
|
||||||
|
for (j = 0; j < 56; j++) {
|
||||||
|
l = PC1[j];
|
||||||
|
m = l & 07;
|
||||||
|
pc1m[j] = (unsigned char)((key[l >> 3] & BYTE_BIT[m]) ? 1 : 0);
|
||||||
|
}
|
||||||
|
for (i = 0; i < 16; i++) {
|
||||||
|
m = i << 1;
|
||||||
|
n = m + 1;
|
||||||
|
kn[m] = kn[n] = 0L;
|
||||||
|
for (j = 0; j < 28; j++) {
|
||||||
|
l = j + TOTAL_ROTATIONS[i];
|
||||||
|
if (l < 28)
|
||||||
|
pcr[j] = pc1m[l];
|
||||||
|
else
|
||||||
|
pcr[j] = pc1m[l - 28];
|
||||||
|
}
|
||||||
|
for (j = 28; j < 56; j++) {
|
||||||
|
l = j + TOTAL_ROTATIONS[i];
|
||||||
|
if (l < 56)
|
||||||
|
pcr[j] = pc1m[l];
|
||||||
|
else
|
||||||
|
pcr[j] = pc1m[l - 28];
|
||||||
|
}
|
||||||
|
for (j = 0; j < 24; j++) {
|
||||||
|
if (pcr[PC2[j]])
|
||||||
|
kn[m] |= BIG_BYTE[j];
|
||||||
|
if (pcr[PC2[j+24]])
|
||||||
|
kn[n] |= BIG_BYTE[j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CookKey (subkeys, kn, encrypt);
|
||||||
|
|
||||||
|
/* Zeroize sensitive information.
|
||||||
|
*/
|
||||||
|
R_memset ((POINTER)pc1m, 0, sizeof (pc1m));
|
||||||
|
R_memset ((POINTER)pcr, 0, sizeof (pcr));
|
||||||
|
R_memset ((POINTER)kn, 0, sizeof (kn));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void CookKey (subkeys, kn, encrypt)
|
||||||
|
UINT4 *subkeys;
|
||||||
|
UINT4 *kn;
|
||||||
|
int encrypt;
|
||||||
|
{
|
||||||
|
UINT4 *cooked, *raw0, *raw1;
|
||||||
|
int increment;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
raw1 = kn;
|
||||||
|
cooked = encrypt ? subkeys : &subkeys[30];
|
||||||
|
increment = encrypt ? 1 : -3;
|
||||||
|
|
||||||
|
for (i = 0; i < 16; i++, raw1++) {
|
||||||
|
raw0 = raw1++;
|
||||||
|
*cooked = (*raw0 & 0x00fc0000L) << 6;
|
||||||
|
*cooked |= (*raw0 & 0x00000fc0L) << 10;
|
||||||
|
*cooked |= (*raw1 & 0x00fc0000L) >> 10;
|
||||||
|
*cooked++ |= (*raw1 & 0x00000fc0L) >> 6;
|
||||||
|
*cooked = (*raw0 & 0x0003f000L) << 12;
|
||||||
|
*cooked |= (*raw0 & 0x0000003fL) << 16;
|
||||||
|
*cooked |= (*raw1 & 0x0003f000L) >> 4;
|
||||||
|
*cooked |= (*raw1 & 0x0000003fL);
|
||||||
|
cooked += increment;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DESFunction (block, subkeys)
|
||||||
|
UINT4 *block;
|
||||||
|
UINT4 *subkeys;
|
||||||
|
{
|
||||||
|
register UINT4 fval, work, right, left;
|
||||||
|
register int round;
|
||||||
|
|
||||||
|
left = block[0];
|
||||||
|
right = block[1];
|
||||||
|
work = ((left >> 4) ^ right) & 0x0f0f0f0fL;
|
||||||
|
right ^= work;
|
||||||
|
left ^= (work << 4);
|
||||||
|
work = ((left >> 16) ^ right) & 0x0000ffffL;
|
||||||
|
right ^= work;
|
||||||
|
left ^= (work << 16);
|
||||||
|
work = ((right >> 2) ^ left) & 0x33333333L;
|
||||||
|
left ^= work;
|
||||||
|
right ^= (work << 2);
|
||||||
|
work = ((right >> 8) ^ left) & 0x00ff00ffL;
|
||||||
|
left ^= work;
|
||||||
|
right ^= (work << 8);
|
||||||
|
right = ((right << 1) | ((right >> 31) & 1L)) & 0xffffffffL;
|
||||||
|
work = (left ^ right) & 0xaaaaaaaaL;
|
||||||
|
left ^= work;
|
||||||
|
right ^= work;
|
||||||
|
left = ((left << 1) | ((left >> 31) & 1L)) & 0xffffffffL;
|
||||||
|
|
||||||
|
for (round = 0; round < 8; round++) {
|
||||||
|
work = (right << 28) | (right >> 4);
|
||||||
|
work ^= *subkeys++;
|
||||||
|
fval = SP7[ work & 0x3fL];
|
||||||
|
fval |= SP5[(work >> 8) & 0x3fL];
|
||||||
|
fval |= SP3[(work >> 16) & 0x3fL];
|
||||||
|
fval |= SP1[(work >> 24) & 0x3fL];
|
||||||
|
work = right ^ *subkeys++;
|
||||||
|
fval |= SP8[ work & 0x3fL];
|
||||||
|
fval |= SP6[(work >> 8) & 0x3fL];
|
||||||
|
fval |= SP4[(work >> 16) & 0x3fL];
|
||||||
|
fval |= SP2[(work >> 24) & 0x3fL];
|
||||||
|
left ^= fval;
|
||||||
|
work = (left << 28) | (left >> 4);
|
||||||
|
work ^= *subkeys++;
|
||||||
|
fval = SP7[ work & 0x3fL];
|
||||||
|
fval |= SP5[(work >> 8) & 0x3fL];
|
||||||
|
fval |= SP3[(work >> 16) & 0x3fL];
|
||||||
|
fval |= SP1[(work >> 24) & 0x3fL];
|
||||||
|
work = left ^ *subkeys++;
|
||||||
|
fval |= SP8[ work & 0x3fL];
|
||||||
|
fval |= SP6[(work >> 8) & 0x3fL];
|
||||||
|
fval |= SP4[(work >> 16) & 0x3fL];
|
||||||
|
fval |= SP2[(work >> 24) & 0x3fL];
|
||||||
|
right ^= fval;
|
||||||
|
}
|
||||||
|
|
||||||
|
right = (right << 31) | (right >> 1);
|
||||||
|
work = (left ^ right) & 0xaaaaaaaaL;
|
||||||
|
left ^= work;
|
||||||
|
right ^= work;
|
||||||
|
left = (left << 31) | (left >> 1);
|
||||||
|
work = ((left >> 8) ^ right) & 0x00ff00ffL;
|
||||||
|
right ^= work;
|
||||||
|
left ^= (work << 8);
|
||||||
|
work = ((left >> 2) ^ right) & 0x33333333L;
|
||||||
|
right ^= work;
|
||||||
|
left ^= (work << 2);
|
||||||
|
work = ((right >> 16) ^ left) & 0x0000ffffL;
|
||||||
|
left ^= work;
|
||||||
|
right ^= (work << 16);
|
||||||
|
work = ((right >> 4) ^ left) & 0x0f0f0f0fL;
|
||||||
|
left ^= work;
|
||||||
|
right ^= (work << 4);
|
||||||
|
*block++ = right;
|
||||||
|
*block = left;
|
||||||
|
}
|
107
lib/rsaref/digit.c
Normal file
107
lib/rsaref/digit.c
Normal file
|
@ -0,0 +1,107 @@
|
||||||
|
/* DIGIT.C - digit arithmetic routines
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Copyright (C) RSA Laboratories, a division of RSA Data Security,
|
||||||
|
Inc., created 1991. All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "global.h"
|
||||||
|
#include "rsaref.h"
|
||||||
|
#include "nn.h"
|
||||||
|
#include "digit.h"
|
||||||
|
|
||||||
|
/* Computes a = b * c, where b and c are digits.
|
||||||
|
|
||||||
|
Lengths: a[2].
|
||||||
|
*/
|
||||||
|
void NN_DigitMult (a, b, c)
|
||||||
|
NN_DIGIT a[2], b, c;
|
||||||
|
{
|
||||||
|
NN_DIGIT t, u;
|
||||||
|
NN_HALF_DIGIT bHigh, bLow, cHigh, cLow;
|
||||||
|
|
||||||
|
bHigh = (NN_HALF_DIGIT)HIGH_HALF (b);
|
||||||
|
bLow = (NN_HALF_DIGIT)LOW_HALF (b);
|
||||||
|
cHigh = (NN_HALF_DIGIT)HIGH_HALF (c);
|
||||||
|
cLow = (NN_HALF_DIGIT)LOW_HALF (c);
|
||||||
|
|
||||||
|
a[0] = (NN_DIGIT)bLow * (NN_DIGIT)cLow;
|
||||||
|
t = (NN_DIGIT)bLow * (NN_DIGIT)cHigh;
|
||||||
|
u = (NN_DIGIT)bHigh * (NN_DIGIT)cLow;
|
||||||
|
a[1] = (NN_DIGIT)bHigh * (NN_DIGIT)cHigh;
|
||||||
|
|
||||||
|
if ((t += u) < u)
|
||||||
|
a[1] += TO_HIGH_HALF (1);
|
||||||
|
u = TO_HIGH_HALF (t);
|
||||||
|
|
||||||
|
if ((a[0] += u) < u)
|
||||||
|
a[1]++;
|
||||||
|
a[1] += HIGH_HALF (t);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sets a = b / c, where a and c are digits.
|
||||||
|
|
||||||
|
Lengths: b[2].
|
||||||
|
Assumes b[1] < c and HIGH_HALF (c) > 0. For efficiency, c should be
|
||||||
|
normalized.
|
||||||
|
*/
|
||||||
|
void NN_DigitDiv (a, b, c)
|
||||||
|
NN_DIGIT *a, b[2], c;
|
||||||
|
{
|
||||||
|
NN_DIGIT t[2], u, v;
|
||||||
|
NN_HALF_DIGIT aHigh, aLow, cHigh, cLow;
|
||||||
|
|
||||||
|
cHigh = (NN_HALF_DIGIT)HIGH_HALF (c);
|
||||||
|
cLow = (NN_HALF_DIGIT)LOW_HALF (c);
|
||||||
|
|
||||||
|
t[0] = b[0];
|
||||||
|
t[1] = b[1];
|
||||||
|
|
||||||
|
/* Underestimate high half of quotient and subtract.
|
||||||
|
*/
|
||||||
|
if (cHigh == MAX_NN_HALF_DIGIT)
|
||||||
|
aHigh = (NN_HALF_DIGIT)HIGH_HALF (t[1]);
|
||||||
|
else
|
||||||
|
aHigh = (NN_HALF_DIGIT)(t[1] / (cHigh + 1));
|
||||||
|
u = (NN_DIGIT)aHigh * (NN_DIGIT)cLow;
|
||||||
|
v = (NN_DIGIT)aHigh * (NN_DIGIT)cHigh;
|
||||||
|
if ((t[0] -= TO_HIGH_HALF (u)) > (MAX_NN_DIGIT - TO_HIGH_HALF (u)))
|
||||||
|
t[1]--;
|
||||||
|
t[1] -= HIGH_HALF (u);
|
||||||
|
t[1] -= v;
|
||||||
|
|
||||||
|
/* Correct estimate.
|
||||||
|
*/
|
||||||
|
while ((t[1] > cHigh) ||
|
||||||
|
((t[1] == cHigh) && (t[0] >= TO_HIGH_HALF (cLow)))) {
|
||||||
|
if ((t[0] -= TO_HIGH_HALF (cLow)) > MAX_NN_DIGIT - TO_HIGH_HALF (cLow))
|
||||||
|
t[1]--;
|
||||||
|
t[1] -= cHigh;
|
||||||
|
aHigh++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Underestimate low half of quotient and subtract.
|
||||||
|
*/
|
||||||
|
if (cHigh == MAX_NN_HALF_DIGIT)
|
||||||
|
aLow = (NN_HALF_DIGIT)LOW_HALF (t[1]);
|
||||||
|
else
|
||||||
|
aLow =
|
||||||
|
(NN_HALF_DIGIT)((TO_HIGH_HALF (t[1]) + HIGH_HALF (t[0])) / (cHigh + 1));
|
||||||
|
u = (NN_DIGIT)aLow * (NN_DIGIT)cLow;
|
||||||
|
v = (NN_DIGIT)aLow * (NN_DIGIT)cHigh;
|
||||||
|
if ((t[0] -= u) > (MAX_NN_DIGIT - u))
|
||||||
|
t[1]--;
|
||||||
|
if ((t[0] -= TO_HIGH_HALF (v)) > (MAX_NN_DIGIT - TO_HIGH_HALF (v)))
|
||||||
|
t[1]--;
|
||||||
|
t[1] -= HIGH_HALF (v);
|
||||||
|
|
||||||
|
/* Correct estimate.
|
||||||
|
*/
|
||||||
|
while ((t[1] > 0) || ((t[1] == 0) && t[0] >= c)) {
|
||||||
|
if ((t[0] -= c) > (MAX_NN_DIGIT - c))
|
||||||
|
t[1]--;
|
||||||
|
aLow++;
|
||||||
|
}
|
||||||
|
|
||||||
|
*a = TO_HIGH_HALF (aHigh) + aLow;
|
||||||
|
}
|
9
lib/rsaref/digit.h
Normal file
9
lib/rsaref/digit.h
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
/* DIGIT.H - header file for DIGIT.C
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Copyright (C) RSA Laboratories, a division of RSA Data Security,
|
||||||
|
Inc., created 1991. All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void NN_DigitMult PROTO_LIST ((NN_DIGIT [2], NN_DIGIT, NN_DIGIT));
|
||||||
|
void NN_DigitDiv PROTO_LIST ((NN_DIGIT *, NN_DIGIT [2], NN_DIGIT));
|
47
lib/rsaref/global.h
Normal file
47
lib/rsaref/global.h
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
/* GLOBAL.H - RSAREF types and constants
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Copyright (C) RSA Laboratories, a division of RSA Data Security,
|
||||||
|
Inc., created 1991. All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _GLOBAL_H_
|
||||||
|
#define _GLOBAL_H_ 1
|
||||||
|
|
||||||
|
/* PROTOTYPES should be set to one if and only if the compiler supports
|
||||||
|
function argument prototyping.
|
||||||
|
The following makes PROTOTYPES default to 1 if it has not already been
|
||||||
|
defined as 0 with C compiler flags.
|
||||||
|
*/
|
||||||
|
#ifndef PROTOTYPES
|
||||||
|
#define PROTOTYPES 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* POINTER defines a generic pointer type */
|
||||||
|
typedef unsigned char *POINTER;
|
||||||
|
|
||||||
|
/* UINT2 defines a two byte word */
|
||||||
|
typedef unsigned short int UINT2;
|
||||||
|
|
||||||
|
/* UINT4 defines a four byte word */
|
||||||
|
typedef unsigned int UINT4;
|
||||||
|
|
||||||
|
#ifndef NULL_PTR
|
||||||
|
#define NULL_PTR ((POINTER)0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef UNUSED_ARG
|
||||||
|
#define UNUSED_ARG(x) x = *(&x);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* PROTO_LIST is defined depending on how PROTOTYPES is defined above.
|
||||||
|
If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it
|
||||||
|
returns an empty list.
|
||||||
|
*/
|
||||||
|
#if PROTOTYPES
|
||||||
|
#define PROTO_LIST(list) list
|
||||||
|
#else
|
||||||
|
#define PROTO_LIST(list) ()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* end _GLOBAL_H_ */
|
45
lib/rsaref/md2.h
Normal file
45
lib/rsaref/md2.h
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
/* MD2.H - header file for MD2C.C
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Copyright (C) 1990-2, RSA Data Security, Inc. Created 1990. All
|
||||||
|
rights reserved.
|
||||||
|
|
||||||
|
License to copy and use this software is granted for
|
||||||
|
non-commercial Internet Privacy-Enhanced Mail provided that it is
|
||||||
|
identified as the "RSA Data Security, Inc. MD2 Message Digest
|
||||||
|
Algorithm" in all material mentioning or referencing this software
|
||||||
|
or this function.
|
||||||
|
|
||||||
|
RSA Data Security, Inc. makes no representations concerning either
|
||||||
|
the merchantability of this software or the suitability of this
|
||||||
|
software for any particular purpose. It is provided "as is"
|
||||||
|
without express or implied warranty of any kind.
|
||||||
|
|
||||||
|
These notices must be retained in any copies of any part of this
|
||||||
|
documentation and/or software.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _MD2_H_
|
||||||
|
#define _MD2_H_ 1
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned char state[16]; /* state */
|
||||||
|
unsigned char checksum[16]; /* checksum */
|
||||||
|
unsigned int count; /* number of bytes, modulo 16 */
|
||||||
|
unsigned char buffer[16]; /* input buffer */
|
||||||
|
} MD2_CTX;
|
||||||
|
|
||||||
|
void MD2Init PROTO_LIST ((MD2_CTX *));
|
||||||
|
void MD2Update PROTO_LIST
|
||||||
|
((MD2_CTX *, unsigned char *, unsigned int));
|
||||||
|
void MD2Final PROTO_LIST ((unsigned char [16], MD2_CTX *));
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
218
lib/rsaref/md2c.c
Normal file
218
lib/rsaref/md2c.c
Normal file
|
@ -0,0 +1,218 @@
|
||||||
|
/* MD2C.C - RSA Data Security, Inc., MD2 message-digest algorithm
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Copyright (C) 1990-2, RSA Data Security, Inc. Created 1990. All
|
||||||
|
rights reserved.
|
||||||
|
|
||||||
|
License to copy and use this software is granted for
|
||||||
|
non-commercial Internet Privacy-Enhanced Mail provided that it is
|
||||||
|
identified as the "RSA Data Security, Inc. MD2 Message Digest
|
||||||
|
Algorithm" in all material mentioning or referencing this software
|
||||||
|
or this function.
|
||||||
|
|
||||||
|
RSA Data Security, Inc. makes no representations concerning either
|
||||||
|
the merchantability of this software or the suitability of this
|
||||||
|
software for any particular purpose. It is provided "as is"
|
||||||
|
without express or implied warranty of any kind.
|
||||||
|
|
||||||
|
These notices must be retained in any copies of any part of this
|
||||||
|
documentation and/or software.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "global.h"
|
||||||
|
#include "md2.h"
|
||||||
|
|
||||||
|
static void MD2Transform PROTO_LIST
|
||||||
|
((unsigned char [16], unsigned char [16], unsigned char [16]));
|
||||||
|
static void MD2_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int));
|
||||||
|
static void MD2_memset PROTO_LIST ((POINTER, int, unsigned int));
|
||||||
|
|
||||||
|
/* Permutation of 0..255 constructed from the digits of pi. It gives a
|
||||||
|
"random" nonlinear byte substitution operation.
|
||||||
|
*/
|
||||||
|
static unsigned char PI_SUBST[256] = {
|
||||||
|
41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6,
|
||||||
|
19, 98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188,
|
||||||
|
76, 130, 202, 30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24,
|
||||||
|
138, 23, 229, 18, 190, 78, 196, 214, 218, 158, 222, 73, 160, 251,
|
||||||
|
245, 142, 187, 47, 238, 122, 169, 104, 121, 145, 21, 178, 7, 63,
|
||||||
|
148, 194, 16, 137, 11, 34, 95, 33, 128, 127, 93, 154, 90, 144, 50,
|
||||||
|
39, 53, 62, 204, 231, 191, 247, 151, 3, 255, 25, 48, 179, 72, 165,
|
||||||
|
181, 209, 215, 94, 146, 42, 172, 86, 170, 198, 79, 184, 56, 210,
|
||||||
|
150, 164, 125, 182, 118, 252, 107, 226, 156, 116, 4, 241, 69, 157,
|
||||||
|
112, 89, 100, 113, 135, 32, 134, 91, 207, 101, 230, 45, 168, 2, 27,
|
||||||
|
96, 37, 173, 174, 176, 185, 246, 28, 70, 97, 105, 52, 64, 126, 15,
|
||||||
|
85, 71, 163, 35, 221, 81, 175, 58, 195, 92, 249, 206, 186, 197,
|
||||||
|
234, 38, 44, 83, 13, 110, 133, 40, 132, 9, 211, 223, 205, 244, 65,
|
||||||
|
129, 77, 82, 106, 220, 55, 200, 108, 193, 171, 250, 36, 225, 123,
|
||||||
|
8, 12, 189, 177, 74, 120, 136, 149, 139, 227, 99, 232, 109, 233,
|
||||||
|
203, 213, 254, 59, 0, 29, 57, 242, 239, 183, 14, 102, 88, 208, 228,
|
||||||
|
166, 119, 114, 248, 235, 117, 75, 10, 49, 68, 80, 180, 143, 237,
|
||||||
|
31, 26, 219, 153, 141, 51, 159, 17, 131, 20
|
||||||
|
};
|
||||||
|
|
||||||
|
static unsigned char *PADDING[] = {
|
||||||
|
(unsigned char *)"",
|
||||||
|
(unsigned char *)"\001",
|
||||||
|
(unsigned char *)"\002\002",
|
||||||
|
(unsigned char *)"\003\003\003",
|
||||||
|
(unsigned char *)"\004\004\004\004",
|
||||||
|
(unsigned char *)"\005\005\005\005\005",
|
||||||
|
(unsigned char *)"\006\006\006\006\006\006",
|
||||||
|
(unsigned char *)"\007\007\007\007\007\007\007",
|
||||||
|
(unsigned char *)"\010\010\010\010\010\010\010\010",
|
||||||
|
(unsigned char *)"\011\011\011\011\011\011\011\011\011",
|
||||||
|
(unsigned char *)"\012\012\012\012\012\012\012\012\012\012",
|
||||||
|
(unsigned char *)"\013\013\013\013\013\013\013\013\013\013\013",
|
||||||
|
(unsigned char *)"\014\014\014\014\014\014\014\014\014\014\014\014",
|
||||||
|
(unsigned char *)
|
||||||
|
"\015\015\015\015\015\015\015\015\015\015\015\015\015",
|
||||||
|
(unsigned char *)
|
||||||
|
"\016\016\016\016\016\016\016\016\016\016\016\016\016\016",
|
||||||
|
(unsigned char *)
|
||||||
|
"\017\017\017\017\017\017\017\017\017\017\017\017\017\017\017",
|
||||||
|
(unsigned char *)
|
||||||
|
"\020\020\020\020\020\020\020\020\020\020\020\020\020\020\020\020"
|
||||||
|
};
|
||||||
|
|
||||||
|
/* MD2 initialization. Begins an MD2 operation, writing a new context.
|
||||||
|
*/
|
||||||
|
void MD2Init (context)
|
||||||
|
MD2_CTX *context; /* context */
|
||||||
|
{
|
||||||
|
context->count = 0;
|
||||||
|
MD2_memset ((POINTER)context->state, 0, sizeof (context->state));
|
||||||
|
MD2_memset
|
||||||
|
((POINTER)context->checksum, 0, sizeof (context->checksum));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* MD2 block update operation. Continues an MD2 message-digest
|
||||||
|
operation, processing another message block, and updating the
|
||||||
|
context.
|
||||||
|
*/
|
||||||
|
void MD2Update (context, input, inputLen)
|
||||||
|
MD2_CTX *context; /* context */
|
||||||
|
unsigned char *input; /* input block */
|
||||||
|
unsigned int inputLen; /* length of input block */
|
||||||
|
{
|
||||||
|
unsigned int i, index, partLen;
|
||||||
|
|
||||||
|
/* Update number of bytes mod 16 */
|
||||||
|
index = context->count;
|
||||||
|
context->count = (index + inputLen) & 0xf;
|
||||||
|
|
||||||
|
partLen = 16 - index;
|
||||||
|
|
||||||
|
/* Transform as many times as possible.
|
||||||
|
*/
|
||||||
|
if (inputLen >= partLen) {
|
||||||
|
MD2_memcpy
|
||||||
|
((POINTER)&context->buffer[index], (POINTER)input, partLen);
|
||||||
|
MD2Transform (context->state, context->checksum, context->buffer);
|
||||||
|
|
||||||
|
for (i = partLen; i + 15 < inputLen; i += 16)
|
||||||
|
MD2Transform (context->state, context->checksum, &input[i]);
|
||||||
|
|
||||||
|
index = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
i = 0;
|
||||||
|
|
||||||
|
/* Buffer remaining input */
|
||||||
|
MD2_memcpy
|
||||||
|
((POINTER)&context->buffer[index], (POINTER)&input[i],
|
||||||
|
inputLen-i);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* MD2 finalization. Ends an MD2 message-digest operation, writing the
|
||||||
|
message digest and zeroizing the context.
|
||||||
|
*/
|
||||||
|
void MD2Final (digest, context)
|
||||||
|
unsigned char digest[16]; /* message digest */
|
||||||
|
MD2_CTX *context; /* context */
|
||||||
|
{
|
||||||
|
unsigned int index, padLen;
|
||||||
|
|
||||||
|
/* Pad out to multiple of 16.
|
||||||
|
*/
|
||||||
|
index = context->count;
|
||||||
|
padLen = 16 - index;
|
||||||
|
MD2Update (context, PADDING[padLen], padLen);
|
||||||
|
|
||||||
|
/* Extend with checksum */
|
||||||
|
MD2Update (context, context->checksum, 16);
|
||||||
|
|
||||||
|
/* Store state in digest */
|
||||||
|
MD2_memcpy ((POINTER)digest, (POINTER)context->state, 16);
|
||||||
|
|
||||||
|
/* Zeroize sensitive information.
|
||||||
|
*/
|
||||||
|
MD2_memset ((POINTER)context, 0, sizeof (*context));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* MD2 basic transformation. Transforms state and updates checksum
|
||||||
|
based on block.
|
||||||
|
*/
|
||||||
|
static void MD2Transform (state, checksum, block)
|
||||||
|
unsigned char state[16];
|
||||||
|
unsigned char checksum[16];
|
||||||
|
unsigned char block[16];
|
||||||
|
{
|
||||||
|
unsigned int i, j, t;
|
||||||
|
unsigned char x[48];
|
||||||
|
|
||||||
|
/* Form encryption block from state, block, state ^ block.
|
||||||
|
*/
|
||||||
|
MD2_memcpy ((POINTER)x, (POINTER)state, 16);
|
||||||
|
MD2_memcpy ((POINTER)x+16, (POINTER)block, 16);
|
||||||
|
for (i = 0; i < 16; i++)
|
||||||
|
x[i+32] = state[i] ^ block[i];
|
||||||
|
|
||||||
|
/* Encrypt block (18 rounds).
|
||||||
|
*/
|
||||||
|
t = 0;
|
||||||
|
for (i = 0; i < 18; i++) {
|
||||||
|
for (j = 0; j < 48; j++)
|
||||||
|
t = x[j] ^= PI_SUBST[t];
|
||||||
|
t = (t + i) & 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Save new state */
|
||||||
|
MD2_memcpy ((POINTER)state, (POINTER)x, 16);
|
||||||
|
|
||||||
|
/* Update checksum.
|
||||||
|
*/
|
||||||
|
t = checksum[15];
|
||||||
|
for (i = 0; i < 16; i++)
|
||||||
|
t = checksum[i] ^= PI_SUBST[block[i] ^ t];
|
||||||
|
|
||||||
|
/* Zeroize sensitive information.
|
||||||
|
*/
|
||||||
|
MD2_memset ((POINTER)x, 0, sizeof (x));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Note: Replace "for loop" with standard memcpy if possible.
|
||||||
|
*/
|
||||||
|
static void MD2_memcpy (output, input, len)
|
||||||
|
POINTER output;
|
||||||
|
POINTER input;
|
||||||
|
unsigned int len;
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for (i = 0; i < len; i++)
|
||||||
|
output[i] = input[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Note: Replace "for loop" with standard memset if possible.
|
||||||
|
*/
|
||||||
|
static void MD2_memset (output, value, len)
|
||||||
|
POINTER output;
|
||||||
|
int value;
|
||||||
|
unsigned int len;
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for (i = 0; i < len; i++)
|
||||||
|
((char *)output)[i] = (char)value;
|
||||||
|
}
|
49
lib/rsaref/md5.h
Normal file
49
lib/rsaref/md5.h
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
/* MD5.H - header file for MD5C.C
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
|
||||||
|
rights reserved.
|
||||||
|
|
||||||
|
License to copy and use this software is granted provided that it
|
||||||
|
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
|
||||||
|
Algorithm" in all material mentioning or referencing this software
|
||||||
|
or this function.
|
||||||
|
|
||||||
|
License is also granted to make and use derivative works provided
|
||||||
|
that such works are identified as "derived from the RSA Data
|
||||||
|
Security, Inc. MD5 Message-Digest Algorithm" in all material
|
||||||
|
mentioning or referencing the derived work.
|
||||||
|
|
||||||
|
RSA Data Security, Inc. makes no representations concerning either
|
||||||
|
the merchantability of this software or the suitability of this
|
||||||
|
software for any particular purpose. It is provided "as is"
|
||||||
|
without express or implied warranty of any kind.
|
||||||
|
|
||||||
|
These notices must be retained in any copies of any part of this
|
||||||
|
documentation and/or software.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _MD5_H_
|
||||||
|
#define _MD5_H_ 1
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* MD5 context. */
|
||||||
|
typedef struct {
|
||||||
|
UINT4 state[4]; /* state (ABCD) */
|
||||||
|
UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */
|
||||||
|
unsigned char buffer[64]; /* input buffer */
|
||||||
|
} MD5_CTX;
|
||||||
|
|
||||||
|
void MD5Init PROTO_LIST ((MD5_CTX *));
|
||||||
|
void MD5Update PROTO_LIST
|
||||||
|
((MD5_CTX *, unsigned char *, unsigned int));
|
||||||
|
void MD5Final PROTO_LIST ((unsigned char [16], MD5_CTX *));
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
334
lib/rsaref/md5c.c
Normal file
334
lib/rsaref/md5c.c
Normal file
|
@ -0,0 +1,334 @@
|
||||||
|
/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
|
||||||
|
rights reserved.
|
||||||
|
|
||||||
|
License to copy and use this software is granted provided that it
|
||||||
|
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
|
||||||
|
Algorithm" in all material mentioning or referencing this software
|
||||||
|
or this function.
|
||||||
|
|
||||||
|
License is also granted to make and use derivative works provided
|
||||||
|
that such works are identified as "derived from the RSA Data
|
||||||
|
Security, Inc. MD5 Message-Digest Algorithm" in all material
|
||||||
|
mentioning or referencing the derived work.
|
||||||
|
|
||||||
|
RSA Data Security, Inc. makes no representations concerning either
|
||||||
|
the merchantability of this software or the suitability of this
|
||||||
|
software for any particular purpose. It is provided "as is"
|
||||||
|
without express or implied warranty of any kind.
|
||||||
|
|
||||||
|
These notices must be retained in any copies of any part of this
|
||||||
|
documentation and/or software.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "global.h"
|
||||||
|
#include "md5.h"
|
||||||
|
|
||||||
|
/* Constants for MD5Transform routine.
|
||||||
|
*/
|
||||||
|
#define S11 7
|
||||||
|
#define S12 12
|
||||||
|
#define S13 17
|
||||||
|
#define S14 22
|
||||||
|
#define S21 5
|
||||||
|
#define S22 9
|
||||||
|
#define S23 14
|
||||||
|
#define S24 20
|
||||||
|
#define S31 4
|
||||||
|
#define S32 11
|
||||||
|
#define S33 16
|
||||||
|
#define S34 23
|
||||||
|
#define S41 6
|
||||||
|
#define S42 10
|
||||||
|
#define S43 15
|
||||||
|
#define S44 21
|
||||||
|
|
||||||
|
static void MD5Transform PROTO_LIST ((UINT4 [4], unsigned char [64]));
|
||||||
|
static void Encode PROTO_LIST
|
||||||
|
((unsigned char *, UINT4 *, unsigned int));
|
||||||
|
static void Decode PROTO_LIST
|
||||||
|
((UINT4 *, unsigned char *, unsigned int));
|
||||||
|
static void MD5_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int));
|
||||||
|
static void MD5_memset PROTO_LIST ((POINTER, int, unsigned int));
|
||||||
|
|
||||||
|
static unsigned char PADDING[64] = {
|
||||||
|
0x80, 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, 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, 0, 0, 0
|
||||||
|
};
|
||||||
|
|
||||||
|
/* F, G, H and I are basic MD5 functions.
|
||||||
|
*/
|
||||||
|
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
|
||||||
|
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
|
||||||
|
#define H(x, y, z) ((x) ^ (y) ^ (z))
|
||||||
|
#define I(x, y, z) ((y) ^ ((x) | (~z)))
|
||||||
|
|
||||||
|
/* ROTATE_LEFT rotates x left n bits.
|
||||||
|
*/
|
||||||
|
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
|
||||||
|
|
||||||
|
/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
|
||||||
|
Rotation is separate from addition to prevent recomputation.
|
||||||
|
*/
|
||||||
|
#define FF(a, b, c, d, x, s, ac) { \
|
||||||
|
(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
|
||||||
|
(a) = ROTATE_LEFT ((a), (s)); \
|
||||||
|
(a) += (b); \
|
||||||
|
}
|
||||||
|
#define GG(a, b, c, d, x, s, ac) { \
|
||||||
|
(a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
|
||||||
|
(a) = ROTATE_LEFT ((a), (s)); \
|
||||||
|
(a) += (b); \
|
||||||
|
}
|
||||||
|
#define HH(a, b, c, d, x, s, ac) { \
|
||||||
|
(a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
|
||||||
|
(a) = ROTATE_LEFT ((a), (s)); \
|
||||||
|
(a) += (b); \
|
||||||
|
}
|
||||||
|
#define II(a, b, c, d, x, s, ac) { \
|
||||||
|
(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
|
||||||
|
(a) = ROTATE_LEFT ((a), (s)); \
|
||||||
|
(a) += (b); \
|
||||||
|
}
|
||||||
|
|
||||||
|
/* MD5 initialization. Begins an MD5 operation, writing a new context.
|
||||||
|
*/
|
||||||
|
void MD5Init (context)
|
||||||
|
MD5_CTX *context; /* context */
|
||||||
|
{
|
||||||
|
context->count[0] = context->count[1] = 0;
|
||||||
|
|
||||||
|
/* Load magic initialization constants.
|
||||||
|
*/
|
||||||
|
context->state[0] = 0x67452301;
|
||||||
|
context->state[1] = 0xefcdab89;
|
||||||
|
context->state[2] = 0x98badcfe;
|
||||||
|
context->state[3] = 0x10325476;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* MD5 block update operation. Continues an MD5 message-digest
|
||||||
|
operation, processing another message block, and updating the
|
||||||
|
context.
|
||||||
|
*/
|
||||||
|
void MD5Update (context, input, inputLen)
|
||||||
|
MD5_CTX *context; /* context */
|
||||||
|
unsigned char *input; /* input block */
|
||||||
|
unsigned int inputLen; /* length of input block */
|
||||||
|
{
|
||||||
|
unsigned int i, index, partLen;
|
||||||
|
|
||||||
|
/* Compute number of bytes mod 64 */
|
||||||
|
index = (unsigned int)((context->count[0] >> 3) & 0x3F);
|
||||||
|
|
||||||
|
/* Update number of bits */
|
||||||
|
if ((context->count[0] += ((UINT4)inputLen << 3))
|
||||||
|
< ((UINT4)inputLen << 3))
|
||||||
|
context->count[1]++;
|
||||||
|
context->count[1] += ((UINT4)inputLen >> 29);
|
||||||
|
|
||||||
|
partLen = 64 - index;
|
||||||
|
|
||||||
|
/* Transform as many times as possible.
|
||||||
|
*/
|
||||||
|
if (inputLen >= partLen) {
|
||||||
|
MD5_memcpy
|
||||||
|
((POINTER)&context->buffer[index], (POINTER)input, partLen);
|
||||||
|
MD5Transform (context->state, context->buffer);
|
||||||
|
|
||||||
|
for (i = partLen; i + 63 < inputLen; i += 64)
|
||||||
|
MD5Transform (context->state, &input[i]);
|
||||||
|
|
||||||
|
index = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
i = 0;
|
||||||
|
|
||||||
|
/* Buffer remaining input */
|
||||||
|
MD5_memcpy
|
||||||
|
((POINTER)&context->buffer[index], (POINTER)&input[i],
|
||||||
|
inputLen-i);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* MD5 finalization. Ends an MD5 message-digest operation, writing the
|
||||||
|
the message digest and zeroizing the context.
|
||||||
|
*/
|
||||||
|
void MD5Final (digest, context)
|
||||||
|
unsigned char digest[16]; /* message digest */
|
||||||
|
MD5_CTX *context; /* context */
|
||||||
|
{
|
||||||
|
unsigned char bits[8];
|
||||||
|
unsigned int index, padLen;
|
||||||
|
|
||||||
|
/* Save number of bits */
|
||||||
|
Encode (bits, context->count, 8);
|
||||||
|
|
||||||
|
/* Pad out to 56 mod 64.
|
||||||
|
*/
|
||||||
|
index = (unsigned int)((context->count[0] >> 3) & 0x3f);
|
||||||
|
padLen = (index < 56) ? (56 - index) : (120 - index);
|
||||||
|
MD5Update (context, PADDING, padLen);
|
||||||
|
|
||||||
|
/* Append length (before padding) */
|
||||||
|
MD5Update (context, bits, 8);
|
||||||
|
|
||||||
|
/* Store state in digest */
|
||||||
|
Encode (digest, context->state, 16);
|
||||||
|
|
||||||
|
/* Zeroize sensitive information.
|
||||||
|
*/
|
||||||
|
MD5_memset ((POINTER)context, 0, sizeof (*context));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* MD5 basic transformation. Transforms state based on block.
|
||||||
|
*/
|
||||||
|
static void MD5Transform (state, block)
|
||||||
|
UINT4 state[4];
|
||||||
|
unsigned char block[64];
|
||||||
|
{
|
||||||
|
UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
|
||||||
|
|
||||||
|
Decode (x, block, 64);
|
||||||
|
|
||||||
|
/* Round 1 */
|
||||||
|
FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
|
||||||
|
FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
|
||||||
|
FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
|
||||||
|
FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
|
||||||
|
FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
|
||||||
|
FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
|
||||||
|
FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
|
||||||
|
FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
|
||||||
|
FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
|
||||||
|
FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
|
||||||
|
FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
|
||||||
|
FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
|
||||||
|
FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
|
||||||
|
FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
|
||||||
|
FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
|
||||||
|
FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
|
||||||
|
|
||||||
|
/* Round 2 */
|
||||||
|
GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
|
||||||
|
GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
|
||||||
|
GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
|
||||||
|
GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
|
||||||
|
GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
|
||||||
|
GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
|
||||||
|
GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
|
||||||
|
GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
|
||||||
|
GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
|
||||||
|
GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
|
||||||
|
GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
|
||||||
|
GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
|
||||||
|
GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
|
||||||
|
GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
|
||||||
|
GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
|
||||||
|
GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
|
||||||
|
|
||||||
|
/* Round 3 */
|
||||||
|
HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
|
||||||
|
HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
|
||||||
|
HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
|
||||||
|
HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
|
||||||
|
HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
|
||||||
|
HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
|
||||||
|
HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
|
||||||
|
HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
|
||||||
|
HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
|
||||||
|
HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
|
||||||
|
HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
|
||||||
|
HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
|
||||||
|
HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
|
||||||
|
HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
|
||||||
|
HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
|
||||||
|
HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
|
||||||
|
|
||||||
|
/* Round 4 */
|
||||||
|
II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
|
||||||
|
II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
|
||||||
|
II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
|
||||||
|
II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
|
||||||
|
II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
|
||||||
|
II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
|
||||||
|
II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
|
||||||
|
II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
|
||||||
|
II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
|
||||||
|
II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
|
||||||
|
II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
|
||||||
|
II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
|
||||||
|
II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
|
||||||
|
II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
|
||||||
|
II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
|
||||||
|
II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
|
||||||
|
|
||||||
|
state[0] += a;
|
||||||
|
state[1] += b;
|
||||||
|
state[2] += c;
|
||||||
|
state[3] += d;
|
||||||
|
|
||||||
|
/* Zeroize sensitive information.
|
||||||
|
*/
|
||||||
|
MD5_memset ((POINTER)x, 0, sizeof (x));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Encodes input (UINT4) into output (unsigned char). Assumes len is
|
||||||
|
a multiple of 4.
|
||||||
|
*/
|
||||||
|
static void Encode (output, input, len)
|
||||||
|
unsigned char *output;
|
||||||
|
UINT4 *input;
|
||||||
|
unsigned int len;
|
||||||
|
{
|
||||||
|
unsigned int i, j;
|
||||||
|
|
||||||
|
for (i = 0, j = 0; j < len; i++, j += 4) {
|
||||||
|
output[j] = (unsigned char)(input[i] & 0xff);
|
||||||
|
output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
|
||||||
|
output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
|
||||||
|
output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Decodes input (unsigned char) into output (UINT4). Assumes len is
|
||||||
|
a multiple of 4.
|
||||||
|
*/
|
||||||
|
static void Decode (output, input, len)
|
||||||
|
UINT4 *output;
|
||||||
|
unsigned char *input;
|
||||||
|
unsigned int len;
|
||||||
|
{
|
||||||
|
unsigned int i, j;
|
||||||
|
|
||||||
|
for (i = 0, j = 0; j < len; i++, j += 4)
|
||||||
|
output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
|
||||||
|
(((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Note: Replace "for loop" with standard memcpy if possible.
|
||||||
|
*/
|
||||||
|
static void MD5_memcpy (output, input, len)
|
||||||
|
POINTER output;
|
||||||
|
POINTER input;
|
||||||
|
unsigned int len;
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for (i = 0; i < len; i++)
|
||||||
|
output[i] = input[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Note: Replace "for loop" with standard memset if possible.
|
||||||
|
*/
|
||||||
|
static void MD5_memset (output, value, len)
|
||||||
|
POINTER output;
|
||||||
|
int value;
|
||||||
|
unsigned int len;
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for (i = 0; i < len; i++)
|
||||||
|
((char *)output)[i] = (char)value;
|
||||||
|
}
|
622
lib/rsaref/nn.c
Normal file
622
lib/rsaref/nn.c
Normal file
|
@ -0,0 +1,622 @@
|
||||||
|
/* NN.C - natural numbers routines
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Copyright (C) RSA Laboratories, a division of RSA Data Security,
|
||||||
|
Inc., created 1991. All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "global.h"
|
||||||
|
#include "rsaref.h"
|
||||||
|
#include "nn.h"
|
||||||
|
#include "digit.h"
|
||||||
|
|
||||||
|
static NN_DIGIT NN_AddDigitMult PROTO_LIST
|
||||||
|
((NN_DIGIT *, NN_DIGIT *, NN_DIGIT, NN_DIGIT *, unsigned int));
|
||||||
|
static NN_DIGIT NN_SubDigitMult PROTO_LIST
|
||||||
|
((NN_DIGIT *, NN_DIGIT *, NN_DIGIT, NN_DIGIT *, unsigned int));
|
||||||
|
|
||||||
|
static unsigned int NN_DigitBits PROTO_LIST ((NN_DIGIT));
|
||||||
|
|
||||||
|
/* Decodes character string b into a, where character string is ordered
|
||||||
|
from most to least significant.
|
||||||
|
|
||||||
|
Lengths: a[digits], b[len].
|
||||||
|
Assumes b[i] = 0 for i < len - digits * NN_DIGIT_LEN. (Otherwise most
|
||||||
|
significant bytes are truncated.)
|
||||||
|
*/
|
||||||
|
void NN_Decode (a, digits, b, len)
|
||||||
|
NN_DIGIT *a;
|
||||||
|
unsigned char *b;
|
||||||
|
unsigned int digits, len;
|
||||||
|
{
|
||||||
|
NN_DIGIT t;
|
||||||
|
int j;
|
||||||
|
unsigned int i, u;
|
||||||
|
|
||||||
|
for (i = 0, j = len - 1; i < digits && j >= 0; i++) {
|
||||||
|
t = 0;
|
||||||
|
for (u = 0; j >= 0 && u < NN_DIGIT_BITS; j--, u += 8)
|
||||||
|
t |= ((NN_DIGIT)b[j]) << u;
|
||||||
|
a[i] = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (; i < digits; i++)
|
||||||
|
a[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Encodes b into character string a, where character string is ordered
|
||||||
|
from most to least significant.
|
||||||
|
|
||||||
|
Lengths: a[len], b[digits].
|
||||||
|
Assumes NN_Bits (b, digits) <= 8 * len. (Otherwise most significant
|
||||||
|
digits are truncated.)
|
||||||
|
*/
|
||||||
|
void NN_Encode (a, len, b, digits)
|
||||||
|
NN_DIGIT *b;
|
||||||
|
unsigned char *a;
|
||||||
|
unsigned int digits, len;
|
||||||
|
{
|
||||||
|
NN_DIGIT t;
|
||||||
|
int j;
|
||||||
|
unsigned int i, u;
|
||||||
|
|
||||||
|
for (i = 0, j = len - 1; i < digits && j >= 0; i++) {
|
||||||
|
t = b[i];
|
||||||
|
for (u = 0; j >= 0 && u < NN_DIGIT_BITS; j--, u += 8)
|
||||||
|
a[j] = (unsigned char)(t >> u);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (; j >= 0; j--)
|
||||||
|
a[j] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Assigns a = b.
|
||||||
|
|
||||||
|
Lengths: a[digits], b[digits].
|
||||||
|
*/
|
||||||
|
void NN_Assign (a, b, digits)
|
||||||
|
NN_DIGIT *a, *b;
|
||||||
|
unsigned int digits;
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for (i = 0; i < digits; i++)
|
||||||
|
a[i] = b[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Assigns a = 0.
|
||||||
|
|
||||||
|
Lengths: a[digits].
|
||||||
|
*/
|
||||||
|
void NN_AssignZero (a, digits)
|
||||||
|
NN_DIGIT *a;
|
||||||
|
unsigned int digits;
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for (i = 0; i < digits; i++)
|
||||||
|
a[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Assigns a = 2^b.
|
||||||
|
|
||||||
|
Lengths: a[digits].
|
||||||
|
Requires b < digits * NN_DIGIT_BITS.
|
||||||
|
*/
|
||||||
|
void NN_Assign2Exp (a, b, digits)
|
||||||
|
NN_DIGIT *a;
|
||||||
|
unsigned int b, digits;
|
||||||
|
{
|
||||||
|
NN_AssignZero (a, digits);
|
||||||
|
|
||||||
|
if (b >= digits * NN_DIGIT_BITS)
|
||||||
|
return;
|
||||||
|
|
||||||
|
a[b / NN_DIGIT_BITS] = (NN_DIGIT)1 << (b % NN_DIGIT_BITS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Computes a = b + c. Returns carry.
|
||||||
|
|
||||||
|
Lengths: a[digits], b[digits], c[digits].
|
||||||
|
*/
|
||||||
|
NN_DIGIT NN_Add (a, b, c, digits)
|
||||||
|
NN_DIGIT *a, *b, *c;
|
||||||
|
unsigned int digits;
|
||||||
|
{
|
||||||
|
NN_DIGIT ai, carry;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
carry = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < digits; i++) {
|
||||||
|
if ((ai = b[i] + carry) < carry)
|
||||||
|
ai = c[i];
|
||||||
|
else if ((ai += c[i]) < c[i])
|
||||||
|
carry = 1;
|
||||||
|
else
|
||||||
|
carry = 0;
|
||||||
|
a[i] = ai;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (carry);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Computes a = b - c. Returns borrow.
|
||||||
|
|
||||||
|
Lengths: a[digits], b[digits], c[digits].
|
||||||
|
*/
|
||||||
|
NN_DIGIT NN_Sub (a, b, c, digits)
|
||||||
|
NN_DIGIT *a, *b, *c;
|
||||||
|
unsigned int digits;
|
||||||
|
{
|
||||||
|
NN_DIGIT ai, borrow;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
borrow = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < digits; i++) {
|
||||||
|
if ((ai = b[i] - borrow) > (MAX_NN_DIGIT - borrow))
|
||||||
|
ai = MAX_NN_DIGIT - c[i];
|
||||||
|
else if ((ai -= c[i]) > (MAX_NN_DIGIT - c[i]))
|
||||||
|
borrow = 1;
|
||||||
|
else
|
||||||
|
borrow = 0;
|
||||||
|
a[i] = ai;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (borrow);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Computes a = b * c.
|
||||||
|
|
||||||
|
Lengths: a[2*digits], b[digits], c[digits].
|
||||||
|
Assumes digits < MAX_NN_DIGITS.
|
||||||
|
*/
|
||||||
|
void NN_Mult (a, b, c, digits)
|
||||||
|
NN_DIGIT *a, *b, *c;
|
||||||
|
unsigned int digits;
|
||||||
|
{
|
||||||
|
NN_DIGIT t[2*MAX_NN_DIGITS];
|
||||||
|
unsigned int bDigits, cDigits, i;
|
||||||
|
|
||||||
|
NN_AssignZero (t, 2 * digits);
|
||||||
|
|
||||||
|
bDigits = NN_Digits (b, digits);
|
||||||
|
cDigits = NN_Digits (c, digits);
|
||||||
|
|
||||||
|
for (i = 0; i < bDigits; i++)
|
||||||
|
t[i+cDigits] += NN_AddDigitMult (&t[i], &t[i], b[i], c, cDigits);
|
||||||
|
|
||||||
|
NN_Assign (a, t, 2 * digits);
|
||||||
|
|
||||||
|
/* Zeroize potentially sensitive information.
|
||||||
|
*/
|
||||||
|
R_memset ((POINTER)t, 0, sizeof (t));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Computes a = b * 2^c (i.e., shifts left c bits), returning carry.
|
||||||
|
|
||||||
|
Lengths: a[digits], b[digits].
|
||||||
|
Requires c < NN_DIGIT_BITS.
|
||||||
|
*/
|
||||||
|
NN_DIGIT NN_LShift (a, b, c, digits)
|
||||||
|
NN_DIGIT *a, *b;
|
||||||
|
unsigned int c, digits;
|
||||||
|
{
|
||||||
|
NN_DIGIT bi, carry;
|
||||||
|
unsigned int i, t;
|
||||||
|
|
||||||
|
if (c >= NN_DIGIT_BITS)
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
t = NN_DIGIT_BITS - c;
|
||||||
|
|
||||||
|
carry = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < digits; i++) {
|
||||||
|
bi = b[i];
|
||||||
|
a[i] = (bi << c) | carry;
|
||||||
|
carry = c ? (bi >> t) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (carry);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Computes a = c div 2^c (i.e., shifts right c bits), returning carry.
|
||||||
|
|
||||||
|
Lengths: a[digits], b[digits].
|
||||||
|
Requires: c < NN_DIGIT_BITS.
|
||||||
|
*/
|
||||||
|
NN_DIGIT NN_RShift (a, b, c, digits)
|
||||||
|
NN_DIGIT *a, *b;
|
||||||
|
unsigned int c, digits;
|
||||||
|
{
|
||||||
|
NN_DIGIT bi, carry;
|
||||||
|
int i;
|
||||||
|
unsigned int t;
|
||||||
|
|
||||||
|
if (c >= NN_DIGIT_BITS)
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
t = NN_DIGIT_BITS - c;
|
||||||
|
|
||||||
|
carry = 0;
|
||||||
|
|
||||||
|
for (i = digits - 1; i >= 0; i--) {
|
||||||
|
bi = b[i];
|
||||||
|
a[i] = (bi >> c) | carry;
|
||||||
|
carry = c ? (bi << t) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (carry);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Computes a = c div d and b = c mod d.
|
||||||
|
|
||||||
|
Lengths: a[cDigits], b[dDigits], c[cDigits], d[dDigits].
|
||||||
|
Assumes d > 0, cDigits < 2 * MAX_NN_DIGITS,
|
||||||
|
dDigits < MAX_NN_DIGITS.
|
||||||
|
*/
|
||||||
|
void NN_Div (a, b, c, cDigits, d, dDigits)
|
||||||
|
NN_DIGIT *a, *b, *c, *d;
|
||||||
|
unsigned int cDigits, dDigits;
|
||||||
|
{
|
||||||
|
NN_DIGIT ai, cc[2*MAX_NN_DIGITS+1], dd[MAX_NN_DIGITS], t;
|
||||||
|
int i;
|
||||||
|
unsigned int ddDigits, shift;
|
||||||
|
|
||||||
|
ddDigits = NN_Digits (d, dDigits);
|
||||||
|
if (ddDigits == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Normalize operands.
|
||||||
|
*/
|
||||||
|
shift = NN_DIGIT_BITS - NN_DigitBits (d[ddDigits-1]);
|
||||||
|
NN_AssignZero (cc, ddDigits);
|
||||||
|
cc[cDigits] = NN_LShift (cc, c, shift, cDigits);
|
||||||
|
NN_LShift (dd, d, shift, ddDigits);
|
||||||
|
t = dd[ddDigits-1];
|
||||||
|
|
||||||
|
NN_AssignZero (a, cDigits);
|
||||||
|
|
||||||
|
for (i = cDigits-ddDigits; i >= 0; i--) {
|
||||||
|
/* Underestimate quotient digit and subtract.
|
||||||
|
*/
|
||||||
|
if (t == MAX_NN_DIGIT)
|
||||||
|
ai = cc[i+ddDigits];
|
||||||
|
else
|
||||||
|
NN_DigitDiv (&ai, &cc[i+ddDigits-1], t + 1);
|
||||||
|
cc[i+ddDigits] -= NN_SubDigitMult (&cc[i], &cc[i], ai, dd, ddDigits);
|
||||||
|
|
||||||
|
/* Correct estimate.
|
||||||
|
*/
|
||||||
|
while (cc[i+ddDigits] || (NN_Cmp (&cc[i], dd, ddDigits) >= 0)) {
|
||||||
|
ai++;
|
||||||
|
cc[i+ddDigits] -= NN_Sub (&cc[i], &cc[i], dd, ddDigits);
|
||||||
|
}
|
||||||
|
|
||||||
|
a[i] = ai;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Restore result.
|
||||||
|
*/
|
||||||
|
NN_AssignZero (b, dDigits);
|
||||||
|
NN_RShift (b, cc, shift, ddDigits);
|
||||||
|
|
||||||
|
/* Zeroize potentially sensitive information.
|
||||||
|
*/
|
||||||
|
R_memset ((POINTER)cc, 0, sizeof (cc));
|
||||||
|
R_memset ((POINTER)dd, 0, sizeof (dd));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Computes a = b mod c.
|
||||||
|
|
||||||
|
Lengths: a[cDigits], b[bDigits], c[cDigits].
|
||||||
|
Assumes c > 0, bDigits < 2 * MAX_NN_DIGITS, cDigits < MAX_NN_DIGITS.
|
||||||
|
*/
|
||||||
|
void NN_Mod (a, b, bDigits, c, cDigits)
|
||||||
|
NN_DIGIT *a, *b, *c;
|
||||||
|
unsigned int bDigits, cDigits;
|
||||||
|
{
|
||||||
|
NN_DIGIT t[2 * MAX_NN_DIGITS];
|
||||||
|
|
||||||
|
NN_Div (t, a, b, bDigits, c, cDigits);
|
||||||
|
|
||||||
|
/* Zeroize potentially sensitive information.
|
||||||
|
*/
|
||||||
|
R_memset ((POINTER)t, 0, sizeof (t));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Computes a = b * c mod d.
|
||||||
|
|
||||||
|
Lengths: a[digits], b[digits], c[digits], d[digits].
|
||||||
|
Assumes d > 0, digits < MAX_NN_DIGITS.
|
||||||
|
*/
|
||||||
|
void NN_ModMult (a, b, c, d, digits)
|
||||||
|
NN_DIGIT *a, *b, *c, *d;
|
||||||
|
unsigned int digits;
|
||||||
|
{
|
||||||
|
NN_DIGIT t[2*MAX_NN_DIGITS];
|
||||||
|
|
||||||
|
NN_Mult (t, b, c, digits);
|
||||||
|
NN_Mod (a, t, 2 * digits, d, digits);
|
||||||
|
|
||||||
|
/* Zeroize potentially sensitive information.
|
||||||
|
*/
|
||||||
|
R_memset ((POINTER)t, 0, sizeof (t));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Computes a = b^c mod d.
|
||||||
|
|
||||||
|
Lengths: a[dDigits], b[dDigits], c[cDigits], d[dDigits].
|
||||||
|
Assumes d > 0, cDigits > 0, dDigits < MAX_NN_DIGITS.
|
||||||
|
*/
|
||||||
|
void NN_ModExp (a, b, c, cDigits, d, dDigits)
|
||||||
|
NN_DIGIT *a, *b, *c, *d;
|
||||||
|
unsigned int cDigits, dDigits;
|
||||||
|
{
|
||||||
|
NN_DIGIT bPower[3][MAX_NN_DIGITS], ci, t[MAX_NN_DIGITS];
|
||||||
|
int i;
|
||||||
|
unsigned int ciBits, j, s;
|
||||||
|
|
||||||
|
/* Store b, b^2 mod d, and b^3 mod d.
|
||||||
|
*/
|
||||||
|
NN_Assign (bPower[0], b, dDigits);
|
||||||
|
NN_ModMult (bPower[1], bPower[0], b, d, dDigits);
|
||||||
|
NN_ModMult (bPower[2], bPower[1], b, d, dDigits);
|
||||||
|
|
||||||
|
NN_ASSIGN_DIGIT (t, 1, dDigits);
|
||||||
|
|
||||||
|
cDigits = NN_Digits (c, cDigits);
|
||||||
|
for (i = cDigits - 1; i >= 0; i--) {
|
||||||
|
ci = c[i];
|
||||||
|
ciBits = NN_DIGIT_BITS;
|
||||||
|
|
||||||
|
/* Scan past leading zero bits of most significant digit.
|
||||||
|
*/
|
||||||
|
if (i == (int)(cDigits - 1)) {
|
||||||
|
while (! DIGIT_2MSB (ci)) {
|
||||||
|
ci <<= 2;
|
||||||
|
ciBits -= 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (j = 0; j < ciBits; j += 2, ci <<= 2) {
|
||||||
|
/* Compute t = t^4 * b^s mod d, where s = two MSB's of ci.
|
||||||
|
*/
|
||||||
|
NN_ModMult (t, t, t, d, dDigits);
|
||||||
|
NN_ModMult (t, t, t, d, dDigits);
|
||||||
|
if ((s = DIGIT_2MSB (ci)) != 0)
|
||||||
|
NN_ModMult (t, t, bPower[s-1], d, dDigits);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NN_Assign (a, t, dDigits);
|
||||||
|
|
||||||
|
/* Zeroize potentially sensitive information.
|
||||||
|
*/
|
||||||
|
R_memset ((POINTER)bPower, 0, sizeof (bPower));
|
||||||
|
R_memset ((POINTER)t, 0, sizeof (t));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Compute a = 1/b mod c, assuming inverse exists.
|
||||||
|
|
||||||
|
Lengths: a[digits], b[digits], c[digits].
|
||||||
|
Assumes gcd (b, c) = 1, digits < MAX_NN_DIGITS.
|
||||||
|
*/
|
||||||
|
void NN_ModInv (a, b, c, digits)
|
||||||
|
NN_DIGIT *a, *b, *c;
|
||||||
|
unsigned int digits;
|
||||||
|
{
|
||||||
|
NN_DIGIT q[MAX_NN_DIGITS], t1[MAX_NN_DIGITS], t3[MAX_NN_DIGITS],
|
||||||
|
u1[MAX_NN_DIGITS], u3[MAX_NN_DIGITS], v1[MAX_NN_DIGITS],
|
||||||
|
v3[MAX_NN_DIGITS], w[2*MAX_NN_DIGITS];
|
||||||
|
int u1Sign;
|
||||||
|
|
||||||
|
/* Apply extended Euclidean algorithm, modified to avoid negative
|
||||||
|
numbers.
|
||||||
|
*/
|
||||||
|
NN_ASSIGN_DIGIT (u1, 1, digits);
|
||||||
|
NN_AssignZero (v1, digits);
|
||||||
|
NN_Assign (u3, b, digits);
|
||||||
|
NN_Assign (v3, c, digits);
|
||||||
|
u1Sign = 1;
|
||||||
|
|
||||||
|
while (! NN_Zero (v3, digits)) {
|
||||||
|
NN_Div (q, t3, u3, digits, v3, digits);
|
||||||
|
NN_Mult (w, q, v1, digits);
|
||||||
|
NN_Add (t1, u1, w, digits);
|
||||||
|
NN_Assign (u1, v1, digits);
|
||||||
|
NN_Assign (v1, t1, digits);
|
||||||
|
NN_Assign (u3, v3, digits);
|
||||||
|
NN_Assign (v3, t3, digits);
|
||||||
|
u1Sign = -u1Sign;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Negate result if sign is negative.
|
||||||
|
*/
|
||||||
|
if (u1Sign < 0)
|
||||||
|
NN_Sub (a, c, u1, digits);
|
||||||
|
else
|
||||||
|
NN_Assign (a, u1, digits);
|
||||||
|
|
||||||
|
/* Zeroize potentially sensitive information.
|
||||||
|
*/
|
||||||
|
R_memset ((POINTER)q, 0, sizeof (q));
|
||||||
|
R_memset ((POINTER)t1, 0, sizeof (t1));
|
||||||
|
R_memset ((POINTER)t3, 0, sizeof (t3));
|
||||||
|
R_memset ((POINTER)u1, 0, sizeof (u1));
|
||||||
|
R_memset ((POINTER)u3, 0, sizeof (u3));
|
||||||
|
R_memset ((POINTER)v1, 0, sizeof (v1));
|
||||||
|
R_memset ((POINTER)v3, 0, sizeof (v3));
|
||||||
|
R_memset ((POINTER)w, 0, sizeof (w));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Computes a = gcd(b, c).
|
||||||
|
|
||||||
|
Lengths: a[digits], b[digits], c[digits].
|
||||||
|
Assumes b > c, digits < MAX_NN_DIGITS.
|
||||||
|
*/
|
||||||
|
void NN_Gcd (a, b, c, digits)
|
||||||
|
NN_DIGIT *a, *b, *c;
|
||||||
|
unsigned int digits;
|
||||||
|
{
|
||||||
|
NN_DIGIT t[MAX_NN_DIGITS], u[MAX_NN_DIGITS], v[MAX_NN_DIGITS];
|
||||||
|
|
||||||
|
NN_Assign (u, b, digits);
|
||||||
|
NN_Assign (v, c, digits);
|
||||||
|
|
||||||
|
while (! NN_Zero (v, digits)) {
|
||||||
|
NN_Mod (t, u, digits, v, digits);
|
||||||
|
NN_Assign (u, v, digits);
|
||||||
|
NN_Assign (v, t, digits);
|
||||||
|
}
|
||||||
|
|
||||||
|
NN_Assign (a, u, digits);
|
||||||
|
|
||||||
|
/* Zeroize potentially sensitive information.
|
||||||
|
*/
|
||||||
|
R_memset ((POINTER)t, 0, sizeof (t));
|
||||||
|
R_memset ((POINTER)u, 0, sizeof (u));
|
||||||
|
R_memset ((POINTER)v, 0, sizeof (v));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns sign of a - b.
|
||||||
|
|
||||||
|
Lengths: a[digits], b[digits].
|
||||||
|
*/
|
||||||
|
int NN_Cmp (a, b, digits)
|
||||||
|
NN_DIGIT *a, *b;
|
||||||
|
unsigned int digits;
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = digits - 1; i >= 0; i--) {
|
||||||
|
if (a[i] > b[i])
|
||||||
|
return (1);
|
||||||
|
if (a[i] < b[i])
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns nonzero iff a is zero.
|
||||||
|
|
||||||
|
Lengths: a[digits].
|
||||||
|
*/
|
||||||
|
int NN_Zero (a, digits)
|
||||||
|
NN_DIGIT *a;
|
||||||
|
unsigned int digits;
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for (i = 0; i < digits; i++)
|
||||||
|
if (a[i])
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns the significant length of a in bits.
|
||||||
|
|
||||||
|
Lengths: a[digits].
|
||||||
|
*/
|
||||||
|
unsigned int NN_Bits (a, digits)
|
||||||
|
NN_DIGIT *a;
|
||||||
|
unsigned int digits;
|
||||||
|
{
|
||||||
|
if ((digits = NN_Digits (a, digits)) == 0)
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
return ((digits - 1) * NN_DIGIT_BITS + NN_DigitBits (a[digits-1]));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns the significant length of a in digits.
|
||||||
|
|
||||||
|
Lengths: a[digits].
|
||||||
|
*/
|
||||||
|
unsigned int NN_Digits (a, digits)
|
||||||
|
NN_DIGIT *a;
|
||||||
|
unsigned int digits;
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = digits - 1; i >= 0; i--)
|
||||||
|
if (a[i])
|
||||||
|
break;
|
||||||
|
|
||||||
|
return (i + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Computes a = b + c*d, where c is a digit. Returns carry.
|
||||||
|
|
||||||
|
Lengths: a[digits], b[digits], d[digits].
|
||||||
|
*/
|
||||||
|
static NN_DIGIT NN_AddDigitMult (a, b, c, d, digits)
|
||||||
|
NN_DIGIT *a, *b, c, *d;
|
||||||
|
unsigned int digits;
|
||||||
|
{
|
||||||
|
NN_DIGIT carry, t[2];
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
if (c == 0)
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
carry = 0;
|
||||||
|
for (i = 0; i < digits; i++) {
|
||||||
|
NN_DigitMult (t, c, d[i]);
|
||||||
|
if ((a[i] = b[i] + carry) < carry)
|
||||||
|
carry = 1;
|
||||||
|
else
|
||||||
|
carry = 0;
|
||||||
|
if ((a[i] += t[0]) < t[0])
|
||||||
|
carry++;
|
||||||
|
carry += t[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
return (carry);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Computes a = b - c*d, where c is a digit. Returns borrow.
|
||||||
|
|
||||||
|
Lengths: a[digits], b[digits], d[digits].
|
||||||
|
*/
|
||||||
|
static NN_DIGIT NN_SubDigitMult (a, b, c, d, digits)
|
||||||
|
NN_DIGIT *a, *b, c, *d;
|
||||||
|
unsigned int digits;
|
||||||
|
{
|
||||||
|
NN_DIGIT borrow, t[2];
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
if (c == 0)
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
borrow = 0;
|
||||||
|
for (i = 0; i < digits; i++) {
|
||||||
|
NN_DigitMult (t, c, d[i]);
|
||||||
|
if ((a[i] = b[i] - borrow) > (MAX_NN_DIGIT - borrow))
|
||||||
|
borrow = 1;
|
||||||
|
else
|
||||||
|
borrow = 0;
|
||||||
|
if ((a[i] -= t[0]) > (MAX_NN_DIGIT - t[0]))
|
||||||
|
borrow++;
|
||||||
|
borrow += t[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
return (borrow);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns the significant length of a in bits, where a is a digit.
|
||||||
|
*/
|
||||||
|
static unsigned int NN_DigitBits (a)
|
||||||
|
NN_DIGIT a;
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for (i = 0; i < NN_DIGIT_BITS; i++, a >>= 1)
|
||||||
|
if (a == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
return (i);
|
||||||
|
}
|
114
lib/rsaref/nn.h
Normal file
114
lib/rsaref/nn.h
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
/* NN.H - header file for NN.C
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Copyright (C) RSA Laboratories, a division of RSA Data Security,
|
||||||
|
Inc., created 1991. All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Type definitions.
|
||||||
|
*/
|
||||||
|
typedef UINT4 NN_DIGIT;
|
||||||
|
typedef UINT2 NN_HALF_DIGIT;
|
||||||
|
|
||||||
|
/* Constants.
|
||||||
|
|
||||||
|
Note: MAX_NN_DIGITS is long enough to hold any RSA modulus, plus
|
||||||
|
one more digit as required by R_GeneratePEMKeys (for n and phiN,
|
||||||
|
whose lengths must be even). All natural numbers have at most
|
||||||
|
MAX_NN_DIGITS digits, except for double-length intermediate values
|
||||||
|
in NN_Mult (t), NN_ModMult (t), NN_ModInv (w), and NN_Div (c).
|
||||||
|
*/
|
||||||
|
/* Length of digit in bits */
|
||||||
|
#define NN_DIGIT_BITS 32
|
||||||
|
#define NN_HALF_DIGIT_BITS 16
|
||||||
|
/* Length of digit in bytes */
|
||||||
|
#define NN_DIGIT_LEN (NN_DIGIT_BITS / 8)
|
||||||
|
/* Maximum length in digits */
|
||||||
|
#define MAX_NN_DIGITS \
|
||||||
|
((MAX_RSA_MODULUS_LEN + NN_DIGIT_LEN - 1) / NN_DIGIT_LEN + 1)
|
||||||
|
/* Maximum digits */
|
||||||
|
#define MAX_NN_DIGIT 0xffffffff
|
||||||
|
#define MAX_NN_HALF_DIGIT 0xffff
|
||||||
|
|
||||||
|
/* Macros.
|
||||||
|
*/
|
||||||
|
#define LOW_HALF(x) ((x) & MAX_NN_HALF_DIGIT)
|
||||||
|
#define HIGH_HALF(x) (((x) >> NN_HALF_DIGIT_BITS) & MAX_NN_HALF_DIGIT)
|
||||||
|
#define TO_HIGH_HALF(x) (((NN_DIGIT)(x)) << NN_HALF_DIGIT_BITS)
|
||||||
|
#define DIGIT_MSB(x) (unsigned int)(((x) >> (NN_DIGIT_BITS - 1)) & 1)
|
||||||
|
#define DIGIT_2MSB(x) (unsigned int)(((x) >> (NN_DIGIT_BITS - 2)) & 3)
|
||||||
|
|
||||||
|
/* CONVERSIONS
|
||||||
|
NN_Decode (a, digits, b, len) Decodes character string b into a.
|
||||||
|
NN_Encode (a, len, b, digits) Encodes a into character string b.
|
||||||
|
|
||||||
|
ASSIGNMENTS
|
||||||
|
NN_Assign (a, b, digits) Assigns a = b.
|
||||||
|
NN_ASSIGN_DIGIT (a, b, digits) Assigns a = b, where b is a digit.
|
||||||
|
NN_AssignZero (a, b, digits) Assigns a = 0.
|
||||||
|
NN_Assign2Exp (a, b, digits) Assigns a = 2^b.
|
||||||
|
|
||||||
|
ARITHMETIC OPERATIONS
|
||||||
|
NN_Add (a, b, c, digits) Computes a = b + c.
|
||||||
|
NN_Sub (a, b, c, digits) Computes a = b - c.
|
||||||
|
NN_Mult (a, b, c, digits) Computes a = b * c.
|
||||||
|
NN_LShift (a, b, c, digits) Computes a = b * 2^c.
|
||||||
|
NN_RShift (a, b, c, digits) Computes a = b / 2^c.
|
||||||
|
NN_Div (a, b, c, cDigits, d, dDigits) Computes a = c div d and b = c mod d.
|
||||||
|
|
||||||
|
NUMBER THEORY
|
||||||
|
NN_Mod (a, b, bDigits, c, cDigits) Computes a = b mod c.
|
||||||
|
NN_ModMult (a, b, c, d, digits) Computes a = b * c mod d.
|
||||||
|
NN_ModExp (a, b, c, cDigits, d, dDigits) Computes a = b^c mod d.
|
||||||
|
NN_ModInv (a, b, c, digits) Computes a = 1/b mod c.
|
||||||
|
NN_Gcd (a, b, c, digits) Computes a = gcd (b, c).
|
||||||
|
|
||||||
|
OTHER OPERATIONS
|
||||||
|
NN_EVEN (a, digits) Returns 1 iff a is even.
|
||||||
|
NN_Cmp (a, b, digits) Returns sign of a - b.
|
||||||
|
NN_EQUAL (a, digits) Returns 1 iff a = b.
|
||||||
|
NN_Zero (a, digits) Returns 1 iff a = 0.
|
||||||
|
NN_Digits (a, digits) Returns significant length of a in digits.
|
||||||
|
NN_Bits (a, digits) Returns significant length of a in bits.
|
||||||
|
*/
|
||||||
|
void NN_Decode PROTO_LIST
|
||||||
|
((NN_DIGIT *, unsigned int, unsigned char *, unsigned int));
|
||||||
|
void NN_Encode PROTO_LIST
|
||||||
|
((unsigned char *, unsigned int, NN_DIGIT *, unsigned int));
|
||||||
|
|
||||||
|
void NN_Assign PROTO_LIST ((NN_DIGIT *, NN_DIGIT *, unsigned int));
|
||||||
|
void NN_AssignZero PROTO_LIST ((NN_DIGIT *, unsigned int));
|
||||||
|
void NN_Assign2Exp PROTO_LIST ((NN_DIGIT *, unsigned int, unsigned int));
|
||||||
|
|
||||||
|
NN_DIGIT NN_Add PROTO_LIST
|
||||||
|
((NN_DIGIT *, NN_DIGIT *, NN_DIGIT *, unsigned int));
|
||||||
|
NN_DIGIT NN_Sub PROTO_LIST
|
||||||
|
((NN_DIGIT *, NN_DIGIT *, NN_DIGIT *, unsigned int));
|
||||||
|
void NN_Mult PROTO_LIST ((NN_DIGIT *, NN_DIGIT *, NN_DIGIT *, unsigned int));
|
||||||
|
void NN_Div PROTO_LIST
|
||||||
|
((NN_DIGIT *, NN_DIGIT *, NN_DIGIT *, unsigned int, NN_DIGIT *,
|
||||||
|
unsigned int));
|
||||||
|
NN_DIGIT NN_LShift PROTO_LIST
|
||||||
|
((NN_DIGIT *, NN_DIGIT *, unsigned int, unsigned int));
|
||||||
|
NN_DIGIT NN_RShift PROTO_LIST
|
||||||
|
((NN_DIGIT *, NN_DIGIT *, unsigned int, unsigned int));
|
||||||
|
|
||||||
|
void NN_Mod PROTO_LIST
|
||||||
|
((NN_DIGIT *, NN_DIGIT *, unsigned int, NN_DIGIT *, unsigned int));
|
||||||
|
void NN_ModMult PROTO_LIST
|
||||||
|
((NN_DIGIT *, NN_DIGIT *, NN_DIGIT *, NN_DIGIT *, unsigned int));
|
||||||
|
void NN_ModExp PROTO_LIST
|
||||||
|
((NN_DIGIT *, NN_DIGIT *, NN_DIGIT *, unsigned int, NN_DIGIT *,
|
||||||
|
unsigned int));
|
||||||
|
void NN_ModInv PROTO_LIST
|
||||||
|
((NN_DIGIT *, NN_DIGIT *, NN_DIGIT *, unsigned int));
|
||||||
|
void NN_Gcd PROTO_LIST ((NN_DIGIT *, NN_DIGIT *, NN_DIGIT *, unsigned int));
|
||||||
|
|
||||||
|
int NN_Cmp PROTO_LIST ((NN_DIGIT *, NN_DIGIT *, unsigned int));
|
||||||
|
int NN_Zero PROTO_LIST ((NN_DIGIT *, unsigned int));
|
||||||
|
unsigned int NN_Bits PROTO_LIST ((NN_DIGIT *, unsigned int));
|
||||||
|
unsigned int NN_Digits PROTO_LIST ((NN_DIGIT *, unsigned int));
|
||||||
|
|
||||||
|
#define NN_ASSIGN_DIGIT(a, b, digits) {NN_AssignZero (a, digits); a[0] = b;}
|
||||||
|
#define NN_EQUAL(a, b, digits) (! NN_Cmp (a, b, digits))
|
||||||
|
#define NN_EVEN(a, digits) (((digits) == 0) || ! (a[0] & 1))
|
143
lib/rsaref/prime.c
Normal file
143
lib/rsaref/prime.c
Normal file
|
@ -0,0 +1,143 @@
|
||||||
|
/* PRIME.C - primality-testing routines
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Copyright (C) RSA Laboratories, a division of RSA Data Security,
|
||||||
|
Inc., created 1991. All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "global.h"
|
||||||
|
#include "rsaref.h"
|
||||||
|
#include "r_random.h"
|
||||||
|
#include "nn.h"
|
||||||
|
#include "prime.h"
|
||||||
|
|
||||||
|
static unsigned int SMALL_PRIMES[] = { 3, 5, 7, 11 };
|
||||||
|
#define SMALL_PRIME_COUNT 4
|
||||||
|
|
||||||
|
static int ProbablePrime PROTO_LIST ((NN_DIGIT *, unsigned int));
|
||||||
|
static int SmallFactor PROTO_LIST ((NN_DIGIT *, unsigned int));
|
||||||
|
static int FermatTest PROTO_LIST ((NN_DIGIT *, unsigned int));
|
||||||
|
|
||||||
|
/* Generates a probable prime a between b and c such that a-1 is
|
||||||
|
divisible by d.
|
||||||
|
|
||||||
|
Lengths: a[digits], b[digits], c[digits], d[digits].
|
||||||
|
Assumes b < c, digits < MAX_NN_DIGITS.
|
||||||
|
|
||||||
|
Returns RE_NEED_RANDOM if randomStruct not seeded, RE_DATA if
|
||||||
|
unsuccessful.
|
||||||
|
*/
|
||||||
|
int GeneratePrime (a, b, c, d, digits, randomStruct)
|
||||||
|
NN_DIGIT *a, *b, *c, *d;
|
||||||
|
unsigned int digits;
|
||||||
|
R_RANDOM_STRUCT *randomStruct;
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
unsigned char block[MAX_NN_DIGITS * NN_DIGIT_LEN];
|
||||||
|
NN_DIGIT t[MAX_NN_DIGITS], u[MAX_NN_DIGITS];
|
||||||
|
|
||||||
|
/* Generate random number between b and c.
|
||||||
|
*/
|
||||||
|
if ((status = R_GenerateBytes (block, digits * NN_DIGIT_LEN, randomStruct)))
|
||||||
|
return (status);
|
||||||
|
NN_Decode (a, digits, block, digits * NN_DIGIT_LEN);
|
||||||
|
NN_Sub (t, c, b, digits);
|
||||||
|
NN_ASSIGN_DIGIT (u, 1, digits);
|
||||||
|
NN_Add (t, t, u, digits);
|
||||||
|
NN_Mod (a, a, digits, t, digits);
|
||||||
|
NN_Add (a, a, b, digits);
|
||||||
|
|
||||||
|
/* Adjust so that a-1 is divisible by d.
|
||||||
|
*/
|
||||||
|
NN_Mod (t, a, digits, d, digits);
|
||||||
|
NN_Sub (a, a, t, digits);
|
||||||
|
NN_Add (a, a, u, digits);
|
||||||
|
if (NN_Cmp (a, b, digits) < 0)
|
||||||
|
NN_Add (a, a, d, digits);
|
||||||
|
if (NN_Cmp (a, c, digits) > 0)
|
||||||
|
NN_Sub (a, a, d, digits);
|
||||||
|
|
||||||
|
/* Search to c in steps of d.
|
||||||
|
*/
|
||||||
|
NN_Assign (t, c, digits);
|
||||||
|
NN_Sub (t, t, d, digits);
|
||||||
|
|
||||||
|
while (! ProbablePrime (a, digits)) {
|
||||||
|
if (NN_Cmp (a, t, digits) > 0)
|
||||||
|
return (RE_DATA);
|
||||||
|
NN_Add (a, a, d, digits);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns nonzero iff a is a probable prime.
|
||||||
|
|
||||||
|
Lengths: a[aDigits].
|
||||||
|
Assumes aDigits < MAX_NN_DIGITS.
|
||||||
|
*/
|
||||||
|
static int ProbablePrime (a, aDigits)
|
||||||
|
NN_DIGIT *a;
|
||||||
|
unsigned int aDigits;
|
||||||
|
{
|
||||||
|
return (! SmallFactor (a, aDigits) && FermatTest (a, aDigits));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns nonzero iff a has a prime factor in SMALL_PRIMES.
|
||||||
|
|
||||||
|
Lengths: a[aDigits].
|
||||||
|
Assumes aDigits < MAX_NN_DIGITS.
|
||||||
|
*/
|
||||||
|
static int SmallFactor (a, aDigits)
|
||||||
|
NN_DIGIT *a;
|
||||||
|
unsigned int aDigits;
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
NN_DIGIT t[1];
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
status = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < SMALL_PRIME_COUNT; i++) {
|
||||||
|
NN_ASSIGN_DIGIT (t, SMALL_PRIMES[i], 1);
|
||||||
|
if ((aDigits == 1) && ! NN_Cmp (a, t, 1))
|
||||||
|
break;
|
||||||
|
NN_Mod (t, a, aDigits, t, 1);
|
||||||
|
if (NN_Zero (t, 1)) {
|
||||||
|
status = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Zeroize sensitive information.
|
||||||
|
*/
|
||||||
|
i = 0;
|
||||||
|
R_memset ((POINTER)t, 0, sizeof (t));
|
||||||
|
|
||||||
|
return (status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns nonzero iff a passes Fermat's test for witness 2.
|
||||||
|
(All primes pass the test, and nearly all composites fail.)
|
||||||
|
|
||||||
|
Lengths: a[aDigits].
|
||||||
|
Assumes aDigits < MAX_NN_DIGITS.
|
||||||
|
*/
|
||||||
|
static int FermatTest (a, aDigits)
|
||||||
|
NN_DIGIT *a;
|
||||||
|
unsigned int aDigits;
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
NN_DIGIT t[MAX_NN_DIGITS], u[MAX_NN_DIGITS];
|
||||||
|
|
||||||
|
NN_ASSIGN_DIGIT (t, 2, aDigits);
|
||||||
|
NN_ModExp (u, t, a, aDigits, a, aDigits);
|
||||||
|
|
||||||
|
status = NN_EQUAL (t, u, aDigits);
|
||||||
|
|
||||||
|
/* Zeroize sensitive information.
|
||||||
|
*/
|
||||||
|
R_memset ((POINTER)u, 0, sizeof (u));
|
||||||
|
|
||||||
|
return (status);
|
||||||
|
}
|
10
lib/rsaref/prime.h
Normal file
10
lib/rsaref/prime.h
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
/* PRIME.H - header file for PRIME.C
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Copyright (C) RSA Laboratories, a division of RSA Data Security,
|
||||||
|
Inc., created 1991. All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int GeneratePrime PROTO_LIST
|
||||||
|
((NN_DIGIT *, NN_DIGIT *, NN_DIGIT *, NN_DIGIT *, unsigned int,
|
||||||
|
R_RANDOM_STRUCT *));
|
145
lib/rsaref/r_dh.c
Normal file
145
lib/rsaref/r_dh.c
Normal file
|
@ -0,0 +1,145 @@
|
||||||
|
/* R_DH.C - Diffie-Hellman routines for RSAREF
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Copyright (C) RSA Laboratories, a division of RSA Data Security,
|
||||||
|
Inc., created 1993. All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "global.h"
|
||||||
|
#include "rsaref.h"
|
||||||
|
#include "r_random.h"
|
||||||
|
#include "nn.h"
|
||||||
|
#include "prime.h"
|
||||||
|
|
||||||
|
/* Generates Diffie-Hellman parameters.
|
||||||
|
*/
|
||||||
|
int R_GenerateDHParams (params, primeBits, subPrimeBits, randomStruct)
|
||||||
|
R_DH_PARAMS *params; /* new Diffie-Hellman parameters */
|
||||||
|
unsigned int primeBits; /* length of prime in bits */
|
||||||
|
unsigned int subPrimeBits; /* length of subprime in bits */
|
||||||
|
R_RANDOM_STRUCT *randomStruct; /* random structure */
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
NN_DIGIT g[MAX_NN_DIGITS], p[MAX_NN_DIGITS], q[MAX_NN_DIGITS],
|
||||||
|
t[MAX_NN_DIGITS], u[MAX_NN_DIGITS], v[MAX_NN_DIGITS];
|
||||||
|
unsigned int pDigits;
|
||||||
|
|
||||||
|
pDigits = (primeBits + NN_DIGIT_BITS - 1) / NN_DIGIT_BITS;
|
||||||
|
|
||||||
|
/* Generate subprime q between 2^(subPrimeBits-1) and
|
||||||
|
2^subPrimeBits-1, searching in steps of 2.
|
||||||
|
*/
|
||||||
|
NN_Assign2Exp (t, subPrimeBits-1, pDigits);
|
||||||
|
NN_Assign (u, t, pDigits);
|
||||||
|
NN_ASSIGN_DIGIT (v, 1, pDigits);
|
||||||
|
NN_Sub (v, t, v, pDigits);
|
||||||
|
NN_Add (u, u, v, pDigits);
|
||||||
|
NN_ASSIGN_DIGIT (v, 2, pDigits);
|
||||||
|
if ((status = GeneratePrime (q, t, u, v, pDigits, randomStruct)))
|
||||||
|
return (status);
|
||||||
|
|
||||||
|
/* Generate prime p between 2^(primeBits-1) and 2^primeBits-1,
|
||||||
|
searching in steps of 2*q.
|
||||||
|
*/
|
||||||
|
NN_Assign2Exp (t, primeBits-1, pDigits);
|
||||||
|
NN_Assign (u, t, pDigits);
|
||||||
|
NN_ASSIGN_DIGIT (v, 1, pDigits);
|
||||||
|
NN_Sub (v, t, v, pDigits);
|
||||||
|
NN_Add (u, u, v, pDigits);
|
||||||
|
NN_LShift (v, q, 1, pDigits);
|
||||||
|
if ((status = GeneratePrime (p, t, u, v, pDigits, randomStruct)))
|
||||||
|
return (status);
|
||||||
|
|
||||||
|
/* Generate generator g for subgroup as 2^((p-1)/q) mod p.
|
||||||
|
*/
|
||||||
|
NN_ASSIGN_DIGIT (g, 2, pDigits);
|
||||||
|
NN_Div (t, u, p, pDigits, q, pDigits);
|
||||||
|
NN_ModExp (g, g, t, pDigits, p, pDigits);
|
||||||
|
|
||||||
|
params->generatorLen = params->primeLen = DH_PRIME_LEN (primeBits);
|
||||||
|
NN_Encode (params->prime, params->primeLen, p, pDigits);
|
||||||
|
NN_Encode (params->generator, params->generatorLen, g, pDigits);
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sets up Diffie-Hellman key agreement. Public value has same length
|
||||||
|
as prime.
|
||||||
|
*/
|
||||||
|
int R_SetupDHAgreement
|
||||||
|
(publicValue, privateValue, privateValueLen, params, randomStruct)
|
||||||
|
unsigned char *publicValue; /* new public value */
|
||||||
|
unsigned char *privateValue; /* new private value */
|
||||||
|
unsigned int privateValueLen; /* length of private value */
|
||||||
|
R_DH_PARAMS *params; /* Diffie-Hellman parameters */
|
||||||
|
R_RANDOM_STRUCT *randomStruct; /* random structure */
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
NN_DIGIT g[MAX_NN_DIGITS], p[MAX_NN_DIGITS], x[MAX_NN_DIGITS],
|
||||||
|
y[MAX_NN_DIGITS];
|
||||||
|
unsigned int pDigits, xDigits;
|
||||||
|
|
||||||
|
NN_Decode (p, MAX_NN_DIGITS, params->prime, params->primeLen);
|
||||||
|
pDigits = NN_Digits (p, MAX_NN_DIGITS);
|
||||||
|
NN_Decode (g, pDigits, params->generator, params->generatorLen);
|
||||||
|
|
||||||
|
/* Generate private value.
|
||||||
|
*/
|
||||||
|
if ((status = R_GenerateBytes (privateValue, privateValueLen, randomStruct)))
|
||||||
|
return (status);
|
||||||
|
NN_Decode (x, pDigits, privateValue, privateValueLen);
|
||||||
|
xDigits = NN_Digits (x, pDigits);
|
||||||
|
|
||||||
|
/* Compute y = g^x mod p.
|
||||||
|
*/
|
||||||
|
NN_ModExp (y, g, x, xDigits, p, pDigits);
|
||||||
|
|
||||||
|
NN_Encode (publicValue, params->primeLen, y, pDigits);
|
||||||
|
|
||||||
|
/* Zeroize sensitive information.
|
||||||
|
*/
|
||||||
|
R_memset ((POINTER)x, 0, sizeof (x));
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Computes agreed key from the other party's public value, a private
|
||||||
|
value, and Diffie-Hellman parameters. Other public value and
|
||||||
|
agreed-upon key have same length as prime.
|
||||||
|
|
||||||
|
Requires otherPublicValue < prime.
|
||||||
|
*/
|
||||||
|
int R_ComputeDHAgreedKey
|
||||||
|
(agreedKey, otherPublicValue, privateValue, privateValueLen, params)
|
||||||
|
unsigned char *agreedKey; /* new agreed key */
|
||||||
|
unsigned char *otherPublicValue; /* other's public value */
|
||||||
|
unsigned char *privateValue; /* private value */
|
||||||
|
unsigned int privateValueLen; /* length of private value */
|
||||||
|
R_DH_PARAMS *params; /* Diffie-Hellman parameters */
|
||||||
|
{
|
||||||
|
NN_DIGIT p[MAX_NN_DIGITS], x[MAX_NN_DIGITS], y[MAX_NN_DIGITS],
|
||||||
|
z[MAX_NN_DIGITS];
|
||||||
|
unsigned int pDigits, xDigits;
|
||||||
|
|
||||||
|
NN_Decode (p, MAX_NN_DIGITS, params->prime, params->primeLen);
|
||||||
|
pDigits = NN_Digits (p, MAX_NN_DIGITS);
|
||||||
|
NN_Decode (x, pDigits, privateValue, privateValueLen);
|
||||||
|
xDigits = NN_Digits (x, pDigits);
|
||||||
|
NN_Decode (y, pDigits, otherPublicValue, params->primeLen);
|
||||||
|
|
||||||
|
if (NN_Cmp (y, p, pDigits) >= 0)
|
||||||
|
return (RE_DATA);
|
||||||
|
|
||||||
|
/* Compute z = y^x mod p.
|
||||||
|
*/
|
||||||
|
NN_ModExp (z, y, x, xDigits, p, pDigits);
|
||||||
|
|
||||||
|
NN_Encode (agreedKey, params->primeLen, z, pDigits);
|
||||||
|
|
||||||
|
/* Zeroize sensitive information.
|
||||||
|
*/
|
||||||
|
R_memset ((POINTER)x, 0, sizeof (x));
|
||||||
|
R_memset ((POINTER)z, 0, sizeof (z));
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
262
lib/rsaref/r_encode.c
Normal file
262
lib/rsaref/r_encode.c
Normal file
|
@ -0,0 +1,262 @@
|
||||||
|
/* R_ENCODE.C - RFC 1113 encoding and decoding routines
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Copyright (C) RSA Laboratories, a division of RSA Data Security,
|
||||||
|
Inc., created 1991. All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "global.h"
|
||||||
|
#include "rsaref.h"
|
||||||
|
|
||||||
|
/* RFC 1113 encoding:
|
||||||
|
|
||||||
|
Value Encoding Value Encoding Value Encoding Value Encoding
|
||||||
|
0 A 17 R 34 i 51 z
|
||||||
|
1 B 18 S 35 j 52 0
|
||||||
|
2 C 19 T 36 k 53 1
|
||||||
|
3 D 20 U 37 l 54 2
|
||||||
|
4 E 21 V 38 m 55 3
|
||||||
|
5 F 22 W 39 n 56 4
|
||||||
|
6 G 23 X 40 o 57 5
|
||||||
|
7 H 24 Y 41 p 58 6
|
||||||
|
8 I 25 Z 42 q 59 7
|
||||||
|
9 J 26 a 43 r 60 8
|
||||||
|
10 K 27 b 44 s 61 9
|
||||||
|
11 L 28 c 45 t 62 +
|
||||||
|
12 M 29 d 46 u 63 /
|
||||||
|
13 N 30 e 47 v
|
||||||
|
14 O 31 f 48 w (pad) =
|
||||||
|
15 P 32 g 49 x
|
||||||
|
16 Q 33 h 50 y
|
||||||
|
*/
|
||||||
|
#define ENCODING(i) \
|
||||||
|
(unsigned char)(((i) < 26) ? ((i) + 0x41) : \
|
||||||
|
(((i) < 52) ? ((i) - 26 + 0x61) : \
|
||||||
|
(((i) < 62) ? ((i) - 52 + 0x30) : \
|
||||||
|
(((i) == 62) ? 0x2b : 0x2f))))
|
||||||
|
#define ENCODING_PAD 0x3d
|
||||||
|
|
||||||
|
#define IS_ENCODING(c) \
|
||||||
|
((((c) >= 0x41) && ((c) <= 0x5a)) || \
|
||||||
|
(((c) >= 0x61) && ((c) <= 0x7a)) || \
|
||||||
|
(((c) >= 0x30) && ((c) <= 0x39)) || \
|
||||||
|
((c) == 0x2b) || \
|
||||||
|
((c) == 0x2f))
|
||||||
|
|
||||||
|
/* assumes IS_ENCODING (c) == 1 */
|
||||||
|
#define DECODING(c) \
|
||||||
|
(((c) == 0x2b) ? 62 : \
|
||||||
|
(((c) == 0x2f) ? 63 : \
|
||||||
|
(((c) <= 0x39) ? ((c) - 0x30 + 52) : \
|
||||||
|
(((c) <= 0x5a) ? ((c) - 0x41) : ((c) - 0x61 + 26)))))
|
||||||
|
|
||||||
|
static void EncodeQuantum PROTO_LIST ((unsigned char [4], unsigned char [3]));
|
||||||
|
static int DecodeQuantum PROTO_LIST ((unsigned char [3], unsigned char [4]));
|
||||||
|
static void EncodeLastQuantum
|
||||||
|
PROTO_LIST ((unsigned char [4], unsigned char *, unsigned int));
|
||||||
|
static int DecodeLastQuantum
|
||||||
|
PROTO_LIST ((unsigned char *, unsigned int *, unsigned char [4]));
|
||||||
|
|
||||||
|
/* This always returns 0. It is an int function for future compatibility.
|
||||||
|
*/
|
||||||
|
int R_EncodePEMBlock (encodedBlock, encodedBlockLen, block, blockLen)
|
||||||
|
unsigned char *encodedBlock; /* encoded block */
|
||||||
|
unsigned int *encodedBlockLen; /* length of encoded block */
|
||||||
|
unsigned char *block; /* block */
|
||||||
|
unsigned int blockLen; /* length of block */
|
||||||
|
{
|
||||||
|
unsigned int i, lastLen;
|
||||||
|
|
||||||
|
if (blockLen < 1) {
|
||||||
|
*encodedBlockLen = 0;
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < (blockLen-1)/3; i++)
|
||||||
|
EncodeQuantum (&encodedBlock[4*i], &block[3*i]);
|
||||||
|
|
||||||
|
lastLen = blockLen - 3*i;
|
||||||
|
EncodeLastQuantum (&encodedBlock[4*i], &block[3*i], lastLen);
|
||||||
|
*encodedBlockLen = 4*i + 4;
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int R_DecodePEMBlock (block, blockLen, encodedBlock, encodedBlockLen)
|
||||||
|
unsigned char *block; /* block */
|
||||||
|
unsigned int *blockLen; /* length of block */
|
||||||
|
unsigned char *encodedBlock; /* encoded block */
|
||||||
|
unsigned int encodedBlockLen; /* length of encoded block */
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
unsigned int i, lastLen;
|
||||||
|
|
||||||
|
if (encodedBlockLen % 4)
|
||||||
|
return (RE_ENCODING);
|
||||||
|
|
||||||
|
if (encodedBlockLen < 1) {
|
||||||
|
*blockLen = 0;
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < (encodedBlockLen-1)/4; i++)
|
||||||
|
if ((status = DecodeQuantum (&block[3*i], &encodedBlock[4*i])))
|
||||||
|
return (status);
|
||||||
|
|
||||||
|
if ((status = DecodeLastQuantum (&block[3*i], &lastLen, &encodedBlock[4*i])))
|
||||||
|
return (status);
|
||||||
|
|
||||||
|
*blockLen = 3*i + lastLen;
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void EncodeQuantum (encodedQuantum, quantum)
|
||||||
|
unsigned char encodedQuantum[4];
|
||||||
|
unsigned char quantum[3];
|
||||||
|
{
|
||||||
|
UINT4 temp;
|
||||||
|
unsigned int a, b, c, d;
|
||||||
|
|
||||||
|
temp = ((UINT4)quantum[0]) << 16;
|
||||||
|
temp |= ((UINT4)quantum[1]) << 8;
|
||||||
|
temp |= (UINT4)quantum[2];
|
||||||
|
|
||||||
|
a = (unsigned int)((temp >> 18) & 0x3f);
|
||||||
|
b = (unsigned int)((temp >> 12) & 0x3f);
|
||||||
|
c = (unsigned int)((temp >> 6) & 0x3f);
|
||||||
|
d = (unsigned int)(temp & 0x3f);
|
||||||
|
|
||||||
|
encodedQuantum[0] = ENCODING (a);
|
||||||
|
encodedQuantum[1] = ENCODING (b);
|
||||||
|
encodedQuantum[2] = ENCODING (c);
|
||||||
|
encodedQuantum[3] = ENCODING (d);
|
||||||
|
|
||||||
|
/* Zeroize potentially sensitive information.
|
||||||
|
*/
|
||||||
|
temp = 0;
|
||||||
|
a = b = c = d = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int DecodeQuantum (quantum, encodedQuantum)
|
||||||
|
unsigned char quantum[3];
|
||||||
|
unsigned char encodedQuantum[4];
|
||||||
|
{
|
||||||
|
UINT4 temp;
|
||||||
|
unsigned int a, b, c, d;
|
||||||
|
|
||||||
|
if (! IS_ENCODING (encodedQuantum[0]) ||
|
||||||
|
! IS_ENCODING (encodedQuantum[1]) ||
|
||||||
|
! IS_ENCODING (encodedQuantum[2]) ||
|
||||||
|
! IS_ENCODING (encodedQuantum[3]))
|
||||||
|
return (RE_ENCODING);
|
||||||
|
|
||||||
|
a = DECODING (encodedQuantum[0]);
|
||||||
|
b = DECODING (encodedQuantum[1]);
|
||||||
|
c = DECODING (encodedQuantum[2]);
|
||||||
|
d = DECODING (encodedQuantum[3]);
|
||||||
|
|
||||||
|
temp = ((UINT4)a) << 18;
|
||||||
|
temp |= ((UINT4)b) << 12;
|
||||||
|
temp |= ((UINT4)c) << 6;
|
||||||
|
temp |= (UINT4)d;
|
||||||
|
|
||||||
|
quantum[0] = (unsigned char)(temp >> 16);
|
||||||
|
quantum[1] = (unsigned char)(temp >> 8);
|
||||||
|
quantum[2] = (unsigned char)temp;
|
||||||
|
|
||||||
|
/* Zeroize potentially sensitive information.
|
||||||
|
*/
|
||||||
|
temp = 0;
|
||||||
|
a = b = c = d = 0;
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void EncodeLastQuantum (encodedQuantum, quantum, quantumLen)
|
||||||
|
unsigned char encodedQuantum[4];
|
||||||
|
unsigned char *quantum;
|
||||||
|
unsigned int quantumLen; /* 1, 2 or 3 */
|
||||||
|
{
|
||||||
|
UINT4 temp;
|
||||||
|
unsigned int a, b, c = 0, d = 0;
|
||||||
|
|
||||||
|
temp = ((UINT4)quantum[0]) << 16;
|
||||||
|
if (quantumLen >= 2)
|
||||||
|
temp |= ((UINT4)quantum[1]) << 8;
|
||||||
|
if (quantumLen == 3)
|
||||||
|
temp |= ((UINT4)quantum[2]);
|
||||||
|
|
||||||
|
a = (unsigned int)((temp >> 18) & 0x3f);
|
||||||
|
b = (unsigned int)((temp >> 12) & 0x3f);
|
||||||
|
if (quantumLen >= 2)
|
||||||
|
c = (unsigned int)((temp >> 6) & 0x3f);
|
||||||
|
if (quantumLen == 3)
|
||||||
|
d = (unsigned int)(temp & 0x3f);
|
||||||
|
|
||||||
|
encodedQuantum[0] = ENCODING (a);
|
||||||
|
encodedQuantum[1] = ENCODING (b);
|
||||||
|
if (quantumLen >= 2)
|
||||||
|
encodedQuantum[2] = ENCODING (c);
|
||||||
|
else
|
||||||
|
encodedQuantum[2] = ENCODING_PAD;
|
||||||
|
if (quantumLen == 3)
|
||||||
|
encodedQuantum[3] = ENCODING (d);
|
||||||
|
else
|
||||||
|
encodedQuantum[3] = ENCODING_PAD;
|
||||||
|
|
||||||
|
/* Zeroize potentially sensitive information.
|
||||||
|
*/
|
||||||
|
temp = 0;
|
||||||
|
a = b = c = d = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int DecodeLastQuantum (quantum, quantumLen, encodedQuantum)
|
||||||
|
unsigned char *quantum;
|
||||||
|
unsigned int *quantumLen; /* 1, 2 or 3 */
|
||||||
|
unsigned char encodedQuantum[4];
|
||||||
|
{
|
||||||
|
UINT4 temp;
|
||||||
|
unsigned int a, b, c = 0, d = 0;
|
||||||
|
|
||||||
|
if (! IS_ENCODING (encodedQuantum[0]) ||
|
||||||
|
! IS_ENCODING (encodedQuantum[1]) ||
|
||||||
|
(! IS_ENCODING (encodedQuantum[2]) &&
|
||||||
|
(encodedQuantum[2] != ENCODING_PAD)) ||
|
||||||
|
(! IS_ENCODING (encodedQuantum[3]) &&
|
||||||
|
(encodedQuantum[3] != ENCODING_PAD)))
|
||||||
|
return (RE_ENCODING);
|
||||||
|
|
||||||
|
if (encodedQuantum[2] == ENCODING_PAD)
|
||||||
|
*quantumLen = 1;
|
||||||
|
else if (encodedQuantum[3] == ENCODING_PAD)
|
||||||
|
*quantumLen = 2;
|
||||||
|
else
|
||||||
|
*quantumLen = 3;
|
||||||
|
|
||||||
|
a = DECODING (encodedQuantum[0]);
|
||||||
|
b = DECODING (encodedQuantum[1]);
|
||||||
|
if (*quantumLen >= 2)
|
||||||
|
c = DECODING (encodedQuantum[2]);
|
||||||
|
if (*quantumLen == 3)
|
||||||
|
d = DECODING (encodedQuantum[3]);
|
||||||
|
|
||||||
|
temp = ((UINT4)a) << 18;
|
||||||
|
temp |= ((UINT4)b) << 12;
|
||||||
|
if (*quantumLen >= 2)
|
||||||
|
temp |= ((UINT4)c) << 6;
|
||||||
|
if (*quantumLen == 3)
|
||||||
|
temp |= ((UINT4)d);
|
||||||
|
|
||||||
|
quantum[0] = (unsigned char)(temp >> 16);
|
||||||
|
if (*quantumLen >= 2)
|
||||||
|
quantum[1] = (unsigned char)(temp >> 8);
|
||||||
|
if (*quantumLen == 3)
|
||||||
|
quantum[2] = (unsigned char)temp;
|
||||||
|
|
||||||
|
/* Zeroize potentially sensitive information.
|
||||||
|
*/
|
||||||
|
temp = 0;
|
||||||
|
a = b = c = d = 0;
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
965
lib/rsaref/r_enhanc.c
Normal file
965
lib/rsaref/r_enhanc.c
Normal file
|
@ -0,0 +1,965 @@
|
||||||
|
/* R_ENHANC.C - cryptographic enhancements for RSAREF
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Copyright (C) RSA Laboratories, a division of RSA Data Security,
|
||||||
|
Inc., created 1991. All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "global.h"
|
||||||
|
#include "rsaref.h"
|
||||||
|
#include "r_random.h"
|
||||||
|
#include "rsa.h"
|
||||||
|
|
||||||
|
/* DigestInfo encoding is DIGEST_INFO_A, then 2 or 5 (for MD2/MD5),
|
||||||
|
then DIGEST_INFO_B, then 16-byte message digest.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static unsigned char DIGEST_INFO_A[] = {
|
||||||
|
0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7,
|
||||||
|
0x0d, 0x02
|
||||||
|
};
|
||||||
|
#define DIGEST_INFO_A_LEN sizeof (DIGEST_INFO_A)
|
||||||
|
|
||||||
|
static unsigned char DIGEST_INFO_B[] = { 0x05, 0x00, 0x04, 0x10 };
|
||||||
|
#define DIGEST_INFO_B_LEN sizeof (DIGEST_INFO_B)
|
||||||
|
|
||||||
|
#define DIGEST_INFO_LEN (DIGEST_INFO_A_LEN + 1 + DIGEST_INFO_B_LEN + 16)
|
||||||
|
|
||||||
|
static unsigned char *PADDING[] = {
|
||||||
|
(unsigned char *)"", (unsigned char *)"\001", (unsigned char *)"\002\002",
|
||||||
|
(unsigned char *)"\003\003\003", (unsigned char *)"\004\004\004\004",
|
||||||
|
(unsigned char *)"\005\005\005\005\005",
|
||||||
|
(unsigned char *)"\006\006\006\006\006\006",
|
||||||
|
(unsigned char *)"\007\007\007\007\007\007\007",
|
||||||
|
(unsigned char *)"\010\010\010\010\010\010\010\010"
|
||||||
|
};
|
||||||
|
|
||||||
|
#define MAX_ENCRYPTED_KEY_LEN MAX_RSA_MODULUS_LEN
|
||||||
|
|
||||||
|
static void R_EncodeDigestInfo PROTO_LIST
|
||||||
|
((unsigned char *, int, unsigned char *));
|
||||||
|
static void EncryptPEMUpdateFinal PROTO_LIST
|
||||||
|
((R_ENVELOPE_CTX *, unsigned char *, unsigned int *, unsigned char *,
|
||||||
|
unsigned int));
|
||||||
|
static int DecryptPEMUpdateFinal PROTO_LIST
|
||||||
|
((R_ENVELOPE_CTX *, unsigned char *, unsigned int *, unsigned char *,
|
||||||
|
unsigned int));
|
||||||
|
static int CipherInit PROTO_LIST
|
||||||
|
((R_ENVELOPE_CTX *, int, unsigned char *, unsigned char *, int));
|
||||||
|
static void CipherUpdate PROTO_LIST
|
||||||
|
((R_ENVELOPE_CTX *, unsigned char *, unsigned char *, unsigned int));
|
||||||
|
static void CipherRestart PROTO_LIST ((R_ENVELOPE_CTX *));
|
||||||
|
|
||||||
|
int R_DigestInit (context, digestAlgorithm)
|
||||||
|
R_DIGEST_CTX *context; /* new context */
|
||||||
|
int digestAlgorithm; /* message-digest algorithm */
|
||||||
|
{
|
||||||
|
context->digestAlgorithm = digestAlgorithm;
|
||||||
|
|
||||||
|
switch (digestAlgorithm) {
|
||||||
|
case DA_MD2:
|
||||||
|
MD2Init (&context->context.md2);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DA_MD5:
|
||||||
|
MD5Init (&context->context.md5);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return (RE_DIGEST_ALGORITHM);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int R_DigestUpdate (context, partIn, partInLen)
|
||||||
|
R_DIGEST_CTX *context; /* context */
|
||||||
|
unsigned char *partIn; /* next data part */
|
||||||
|
unsigned int partInLen; /* length of next data part */
|
||||||
|
{
|
||||||
|
if (context->digestAlgorithm == DA_MD2)
|
||||||
|
MD2Update (&context->context.md2, partIn, partInLen);
|
||||||
|
else
|
||||||
|
MD5Update (&context->context.md5, partIn, partInLen);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int R_DigestFinal (context, digest, digestLen)
|
||||||
|
R_DIGEST_CTX *context; /* context */
|
||||||
|
unsigned char *digest; /* message digest */
|
||||||
|
unsigned int *digestLen; /* length of message digest */
|
||||||
|
{
|
||||||
|
*digestLen = 16;
|
||||||
|
if (context->digestAlgorithm == DA_MD2)
|
||||||
|
MD2Final (digest, &context->context.md2);
|
||||||
|
else
|
||||||
|
MD5Final (digest, &context->context.md5);
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int R_SignInit (context, digestAlgorithm)
|
||||||
|
R_SIGNATURE_CTX *context; /* new context */
|
||||||
|
int digestAlgorithm; /* message-digest algorithm */
|
||||||
|
{
|
||||||
|
return (R_DigestInit (&context->digestContext, digestAlgorithm));
|
||||||
|
}
|
||||||
|
|
||||||
|
int R_SignUpdate (context, partIn, partInLen)
|
||||||
|
R_SIGNATURE_CTX *context; /* context */
|
||||||
|
unsigned char *partIn; /* next data part */
|
||||||
|
unsigned int partInLen; /* length of next data part */
|
||||||
|
{
|
||||||
|
return (R_DigestUpdate (&context->digestContext, partIn, partInLen));
|
||||||
|
}
|
||||||
|
|
||||||
|
int R_SignFinal (context, signature, signatureLen, privateKey)
|
||||||
|
R_SIGNATURE_CTX *context; /* context */
|
||||||
|
unsigned char *signature; /* signature */
|
||||||
|
unsigned int *signatureLen; /* length of signature */
|
||||||
|
R_RSA_PRIVATE_KEY *privateKey; /* signer's RSA private key */
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
unsigned char digest[MAX_DIGEST_LEN], digestInfo[DIGEST_INFO_LEN];
|
||||||
|
unsigned int digestLen;
|
||||||
|
|
||||||
|
do {
|
||||||
|
if ((status = R_DigestFinal (&context->digestContext, digest, &digestLen))
|
||||||
|
!= 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
R_EncodeDigestInfo
|
||||||
|
(digestInfo, context->digestContext.digestAlgorithm, digest);
|
||||||
|
|
||||||
|
if (RSAPrivateEncrypt
|
||||||
|
(signature, signatureLen, digestInfo, DIGEST_INFO_LEN, privateKey)
|
||||||
|
!= 0) {
|
||||||
|
status = RE_PRIVATE_KEY;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reset for another verification. Assume Init won't fail */
|
||||||
|
R_DigestInit
|
||||||
|
(&context->digestContext, context->digestContext.digestAlgorithm);
|
||||||
|
} while (0);
|
||||||
|
|
||||||
|
/* Zeroize potentially sensitive information.
|
||||||
|
*/
|
||||||
|
R_memset ((POINTER)digest, 0, sizeof (digest));
|
||||||
|
R_memset ((POINTER)digestInfo, 0, sizeof (digestInfo));
|
||||||
|
|
||||||
|
return (status);
|
||||||
|
}
|
||||||
|
|
||||||
|
int R_VerifyInit (context, digestAlgorithm)
|
||||||
|
R_SIGNATURE_CTX *context; /* new context */
|
||||||
|
int digestAlgorithm; /* message-digest algorithm */
|
||||||
|
{
|
||||||
|
return (R_DigestInit (&context->digestContext, digestAlgorithm));
|
||||||
|
}
|
||||||
|
|
||||||
|
int R_VerifyUpdate (context, partIn, partInLen)
|
||||||
|
R_SIGNATURE_CTX *context; /* context */
|
||||||
|
unsigned char *partIn; /* next data part */
|
||||||
|
unsigned int partInLen; /* length of next data part */
|
||||||
|
{
|
||||||
|
return (R_DigestUpdate (&context->digestContext, partIn, partInLen));
|
||||||
|
}
|
||||||
|
|
||||||
|
int R_VerifyFinal (context, signature, signatureLen, publicKey)
|
||||||
|
R_SIGNATURE_CTX *context; /* context */
|
||||||
|
unsigned char *signature; /* signature */
|
||||||
|
unsigned int signatureLen; /* length of signature */
|
||||||
|
R_RSA_PUBLIC_KEY *publicKey; /* signer's RSA public key */
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
unsigned char digest[MAX_DIGEST_LEN], digestInfo[DIGEST_INFO_LEN],
|
||||||
|
originalDigestInfo[MAX_SIGNATURE_LEN];
|
||||||
|
unsigned int originalDigestInfoLen, digestLen;
|
||||||
|
|
||||||
|
if (signatureLen > MAX_SIGNATURE_LEN)
|
||||||
|
return (RE_LEN);
|
||||||
|
|
||||||
|
status = 0;
|
||||||
|
do {
|
||||||
|
if ((status = R_DigestFinal (&context->digestContext, digest, &digestLen))
|
||||||
|
!= 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
R_EncodeDigestInfo
|
||||||
|
(digestInfo, context->digestContext.digestAlgorithm, digest);
|
||||||
|
|
||||||
|
if (RSAPublicDecrypt
|
||||||
|
(originalDigestInfo, &originalDigestInfoLen, signature, signatureLen,
|
||||||
|
publicKey) != 0) {
|
||||||
|
status = RE_PUBLIC_KEY;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((originalDigestInfoLen != DIGEST_INFO_LEN) ||
|
||||||
|
(R_memcmp
|
||||||
|
((POINTER)originalDigestInfo, (POINTER)digestInfo,
|
||||||
|
DIGEST_INFO_LEN))) {
|
||||||
|
status = RE_SIGNATURE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reset for another verification. Assume Init won't fail */
|
||||||
|
R_DigestInit
|
||||||
|
(&context->digestContext, context->digestContext.digestAlgorithm);
|
||||||
|
} while (0);
|
||||||
|
|
||||||
|
/* Zeroize potentially sensitive information.
|
||||||
|
*/
|
||||||
|
R_memset ((POINTER)digest, 0, sizeof (digest));
|
||||||
|
R_memset ((POINTER)digestInfo, 0, sizeof (digestInfo));
|
||||||
|
R_memset ((POINTER)originalDigestInfo, 0, sizeof (originalDigestInfo));
|
||||||
|
|
||||||
|
return (status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Caller must ASCII recode the encrypted keys if desired.
|
||||||
|
*/
|
||||||
|
int R_SealInit
|
||||||
|
(context, encryptedKeys, encryptedKeyLens, iv, publicKeyCount, publicKeys,
|
||||||
|
encryptionAlgorithm, randomStruct)
|
||||||
|
R_ENVELOPE_CTX *context; /* new context */
|
||||||
|
unsigned char **encryptedKeys; /* encrypted keys */
|
||||||
|
unsigned int *encryptedKeyLens; /* lengths of encrypted keys */
|
||||||
|
unsigned char iv[8]; /* initialization vector */
|
||||||
|
unsigned int publicKeyCount; /* number of public keys */
|
||||||
|
R_RSA_PUBLIC_KEY **publicKeys; /* public keys */
|
||||||
|
int encryptionAlgorithm; /* data encryption algorithm */
|
||||||
|
R_RANDOM_STRUCT *randomStruct; /* random structure */
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
unsigned char key[24];
|
||||||
|
unsigned int keyLen, i;
|
||||||
|
|
||||||
|
do {
|
||||||
|
context->encryptionAlgorithm = encryptionAlgorithm;
|
||||||
|
|
||||||
|
keyLen = (encryptionAlgorithm == EA_DES_CBC) ? 8 : 24;
|
||||||
|
if ((status = R_GenerateBytes (key, keyLen, randomStruct)) != 0)
|
||||||
|
break;
|
||||||
|
if ((status = R_GenerateBytes (iv, 8, randomStruct)) != 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (encryptionAlgorithm == EA_DES_EDE2_CBC)
|
||||||
|
/* Make both E keys the same */
|
||||||
|
R_memcpy ((POINTER)(key + 16), (POINTER)key, 8);
|
||||||
|
|
||||||
|
if ((status = CipherInit (context, encryptionAlgorithm, key, iv, 1)) != 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
for (i = 0; i < publicKeyCount; ++i) {
|
||||||
|
if (RSAPublicEncrypt
|
||||||
|
(encryptedKeys[i], &encryptedKeyLens[i], key, keyLen,
|
||||||
|
publicKeys[i], randomStruct)) {
|
||||||
|
status = RE_PUBLIC_KEY;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (status != 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
context->bufferLen = 0;
|
||||||
|
} while (0);
|
||||||
|
|
||||||
|
/* Zeroize sensitive information.
|
||||||
|
*/
|
||||||
|
R_memset ((POINTER)key, 0, sizeof (key));
|
||||||
|
|
||||||
|
return (status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Assume partOut buffer is at least partInLen + 7, since this may flush
|
||||||
|
buffered input.
|
||||||
|
*/
|
||||||
|
int R_SealUpdate (context, partOut, partOutLen, partIn, partInLen)
|
||||||
|
R_ENVELOPE_CTX *context; /* context */
|
||||||
|
unsigned char *partOut; /* next encrypted data part */
|
||||||
|
unsigned int *partOutLen; /* length of next encrypted data part */
|
||||||
|
unsigned char *partIn; /* next data part */
|
||||||
|
unsigned int partInLen; /* length of next data part */
|
||||||
|
{
|
||||||
|
unsigned int tempLen;
|
||||||
|
|
||||||
|
tempLen = 8 - context->bufferLen;
|
||||||
|
if (partInLen < tempLen) {
|
||||||
|
/* Just accumulate into buffer.
|
||||||
|
*/
|
||||||
|
R_memcpy
|
||||||
|
((POINTER)(context->buffer + context->bufferLen), (POINTER)partIn,
|
||||||
|
partInLen);
|
||||||
|
context->bufferLen += partInLen;
|
||||||
|
*partOutLen = 0;
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fill the buffer and encrypt.
|
||||||
|
*/
|
||||||
|
R_memcpy
|
||||||
|
((POINTER)(context->buffer + context->bufferLen), (POINTER)partIn,
|
||||||
|
tempLen);
|
||||||
|
CipherUpdate (context, partOut, context->buffer, 8);
|
||||||
|
partIn += tempLen;
|
||||||
|
partInLen -= tempLen;
|
||||||
|
partOut += 8;
|
||||||
|
*partOutLen = 8;
|
||||||
|
|
||||||
|
/* Encrypt as many 8-byte blocks as possible.
|
||||||
|
*/
|
||||||
|
tempLen = 8 * (partInLen / 8);
|
||||||
|
CipherUpdate (context, partOut, partIn, tempLen);
|
||||||
|
partIn += tempLen;
|
||||||
|
partInLen -= tempLen;
|
||||||
|
*partOutLen += tempLen;
|
||||||
|
|
||||||
|
/* Length is now less than 8, so copy remainder to buffer.
|
||||||
|
*/
|
||||||
|
R_memcpy
|
||||||
|
((POINTER)context->buffer, (POINTER)partIn,
|
||||||
|
context->bufferLen = partInLen);
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Assume partOut buffer is at least 8 bytes.
|
||||||
|
*/
|
||||||
|
int R_SealFinal (context, partOut, partOutLen)
|
||||||
|
R_ENVELOPE_CTX *context; /* context */
|
||||||
|
unsigned char *partOut; /* last encrypted data part */
|
||||||
|
unsigned int *partOutLen; /* length of last encrypted data part */
|
||||||
|
{
|
||||||
|
unsigned int padLen;
|
||||||
|
|
||||||
|
/* Pad and encrypt final block.
|
||||||
|
*/
|
||||||
|
padLen = 8 - context->bufferLen;
|
||||||
|
R_memset
|
||||||
|
((POINTER)(context->buffer + context->bufferLen), (int)padLen, padLen);
|
||||||
|
CipherUpdate (context, partOut, context->buffer, 8);
|
||||||
|
*partOutLen = 8;
|
||||||
|
|
||||||
|
/* Restart the context.
|
||||||
|
*/
|
||||||
|
CipherRestart (context);
|
||||||
|
context->bufferLen = 0;
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Assume caller has already ASCII decoded the encryptedKey if necessary.
|
||||||
|
*/
|
||||||
|
int R_OpenInit
|
||||||
|
(context, encryptionAlgorithm, encryptedKey, encryptedKeyLen, iv, privateKey)
|
||||||
|
R_ENVELOPE_CTX *context; /* new context */
|
||||||
|
int encryptionAlgorithm; /* data encryption algorithm */
|
||||||
|
unsigned char *encryptedKey; /* encrypted data encryption key */
|
||||||
|
unsigned int encryptedKeyLen; /* length of encrypted key */
|
||||||
|
unsigned char iv[8]; /* initialization vector */
|
||||||
|
R_RSA_PRIVATE_KEY *privateKey; /* recipient's RSA private key */
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
unsigned char key[MAX_ENCRYPTED_KEY_LEN];
|
||||||
|
unsigned int keyLen;
|
||||||
|
|
||||||
|
if (encryptedKeyLen > MAX_ENCRYPTED_KEY_LEN)
|
||||||
|
return (RE_LEN);
|
||||||
|
|
||||||
|
do {
|
||||||
|
context->encryptionAlgorithm = encryptionAlgorithm;
|
||||||
|
|
||||||
|
if (RSAPrivateDecrypt
|
||||||
|
(key, &keyLen, encryptedKey, encryptedKeyLen, privateKey)) {
|
||||||
|
status = RE_PRIVATE_KEY;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (encryptionAlgorithm == EA_DES_CBC) {
|
||||||
|
if (keyLen != 8) {
|
||||||
|
status = RE_PRIVATE_KEY;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (keyLen != 24) {
|
||||||
|
status = RE_PRIVATE_KEY;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((status = CipherInit (context, encryptionAlgorithm, key, iv, 0)) != 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
context->bufferLen = 0;
|
||||||
|
} while (0);
|
||||||
|
|
||||||
|
/* Zeroize sensitive information.
|
||||||
|
*/
|
||||||
|
R_memset ((POINTER)key, 0, sizeof (key));
|
||||||
|
|
||||||
|
return (status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Assume partOut buffer is at least partInLen + 7, since this may flush
|
||||||
|
buffered input. Always leaves at least one byte in buffer.
|
||||||
|
*/
|
||||||
|
int R_OpenUpdate (context, partOut, partOutLen, partIn, partInLen)
|
||||||
|
R_ENVELOPE_CTX *context; /* context */
|
||||||
|
unsigned char *partOut; /* next recovered data part */
|
||||||
|
unsigned int *partOutLen; /* length of next recovered data part */
|
||||||
|
unsigned char *partIn; /* next encrypted data part */
|
||||||
|
unsigned int partInLen; /* length of next encrypted data part */
|
||||||
|
{
|
||||||
|
unsigned int tempLen;
|
||||||
|
|
||||||
|
tempLen = 8 - context->bufferLen;
|
||||||
|
if (partInLen <= tempLen) {
|
||||||
|
/* Just accumulate into buffer.
|
||||||
|
*/
|
||||||
|
R_memcpy
|
||||||
|
((POINTER)(context->buffer + context->bufferLen), (POINTER)partIn,
|
||||||
|
partInLen);
|
||||||
|
context->bufferLen += partInLen;
|
||||||
|
*partOutLen = 0;
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fill the buffer and decrypt. We know that there will be more left
|
||||||
|
in partIn after decrypting the buffer.
|
||||||
|
*/
|
||||||
|
R_memcpy
|
||||||
|
((POINTER)(context->buffer + context->bufferLen), (POINTER)partIn,
|
||||||
|
tempLen);
|
||||||
|
CipherUpdate (context, partOut, context->buffer, 8);
|
||||||
|
partIn += tempLen;
|
||||||
|
partInLen -= tempLen;
|
||||||
|
partOut += 8;
|
||||||
|
*partOutLen = 8;
|
||||||
|
|
||||||
|
/* Decrypt as many 8 byte blocks as possible, leaving at least one byte
|
||||||
|
in partIn.
|
||||||
|
*/
|
||||||
|
tempLen = 8 * ((partInLen - 1) / 8);
|
||||||
|
CipherUpdate (context, partOut, partIn, tempLen);
|
||||||
|
partIn += tempLen;
|
||||||
|
partInLen -= tempLen;
|
||||||
|
*partOutLen += tempLen;
|
||||||
|
|
||||||
|
/* Length is between 1 and 8, so copy into buffer.
|
||||||
|
*/
|
||||||
|
R_memcpy
|
||||||
|
((POINTER)context->buffer, (POINTER)partIn,
|
||||||
|
context->bufferLen = partInLen);
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Assume partOut buffer is at least 7 bytes.
|
||||||
|
*/
|
||||||
|
int R_OpenFinal (context, partOut, partOutLen)
|
||||||
|
R_ENVELOPE_CTX *context; /* context */
|
||||||
|
unsigned char *partOut; /* last recovered data part */
|
||||||
|
unsigned int *partOutLen; /* length of last recovered data part */
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
unsigned char lastPart[8];
|
||||||
|
unsigned int padLen;
|
||||||
|
|
||||||
|
status = 0;
|
||||||
|
do {
|
||||||
|
if (context->bufferLen == 0)
|
||||||
|
/* There was no input data to decrypt */
|
||||||
|
*partOutLen = 0;
|
||||||
|
else {
|
||||||
|
if (context->bufferLen != 8) {
|
||||||
|
status = RE_KEY;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Decrypt and strip padding from final block which is in buffer.
|
||||||
|
*/
|
||||||
|
CipherUpdate (context, lastPart, context->buffer, 8);
|
||||||
|
|
||||||
|
padLen = lastPart[7];
|
||||||
|
if (padLen == 0 || padLen > 8) {
|
||||||
|
status = RE_KEY;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (R_memcmp
|
||||||
|
((POINTER)&lastPart[8 - padLen], PADDING[padLen], padLen) != 0) {
|
||||||
|
status = RE_KEY;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
R_memcpy ((POINTER)partOut, (POINTER)lastPart, *partOutLen = 8 - padLen);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Restart the context.
|
||||||
|
*/
|
||||||
|
CipherRestart (context);
|
||||||
|
context->bufferLen = 0;
|
||||||
|
} while (0);
|
||||||
|
|
||||||
|
/* Zeroize sensitive information.
|
||||||
|
*/
|
||||||
|
R_memset ((POINTER)lastPart, 0, sizeof (lastPart));
|
||||||
|
|
||||||
|
return (status);
|
||||||
|
}
|
||||||
|
|
||||||
|
int R_SignPEMBlock
|
||||||
|
(encodedContent, encodedContentLen, encodedSignature, encodedSignatureLen,
|
||||||
|
content, contentLen, recode, digestAlgorithm, privateKey)
|
||||||
|
unsigned char *encodedContent; /* encoded content */
|
||||||
|
unsigned int *encodedContentLen; /* length of encoded content */
|
||||||
|
unsigned char *encodedSignature; /* encoded signature */
|
||||||
|
unsigned int *encodedSignatureLen; /* length of encoded signature */
|
||||||
|
unsigned char *content; /* content */
|
||||||
|
unsigned int contentLen; /* length of content */
|
||||||
|
int recode; /* recoding flag */
|
||||||
|
int digestAlgorithm; /* message-digest algorithm */
|
||||||
|
R_RSA_PRIVATE_KEY *privateKey; /* signer's RSA private key */
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
unsigned char signature[MAX_SIGNATURE_LEN];
|
||||||
|
unsigned int signatureLen;
|
||||||
|
|
||||||
|
if ((status = R_SignBlock
|
||||||
|
(signature, &signatureLen, content, contentLen, digestAlgorithm,
|
||||||
|
privateKey)) != 0)
|
||||||
|
return (status);
|
||||||
|
|
||||||
|
R_EncodePEMBlock
|
||||||
|
(encodedSignature, encodedSignatureLen, signature, signatureLen);
|
||||||
|
|
||||||
|
if (recode)
|
||||||
|
R_EncodePEMBlock
|
||||||
|
(encodedContent, encodedContentLen, content, contentLen);
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int R_SignBlock
|
||||||
|
(signature, signatureLen, block, blockLen, digestAlgorithm, privateKey)
|
||||||
|
unsigned char *signature; /* signature */
|
||||||
|
unsigned int *signatureLen; /* length of signature */
|
||||||
|
unsigned char *block; /* block */
|
||||||
|
unsigned int blockLen; /* length of block */
|
||||||
|
int digestAlgorithm; /* message-digest algorithm */
|
||||||
|
R_RSA_PRIVATE_KEY *privateKey; /* signer's RSA private key */
|
||||||
|
{
|
||||||
|
R_SIGNATURE_CTX context;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
do {
|
||||||
|
if ((status = R_SignInit (&context, digestAlgorithm)) != 0)
|
||||||
|
break;
|
||||||
|
if ((status = R_SignUpdate (&context, block, blockLen)) != 0)
|
||||||
|
break;
|
||||||
|
if ((status = R_SignFinal (&context, signature, signatureLen, privateKey))
|
||||||
|
!= 0)
|
||||||
|
break;
|
||||||
|
} while (0);
|
||||||
|
|
||||||
|
/* Zeroize sensitive information. */
|
||||||
|
R_memset ((POINTER)&context, 0, sizeof (context));
|
||||||
|
|
||||||
|
return (status);
|
||||||
|
}
|
||||||
|
|
||||||
|
int R_VerifyPEMSignature
|
||||||
|
(content, contentLen, encodedContent, encodedContentLen, encodedSignature,
|
||||||
|
encodedSignatureLen, recode, digestAlgorithm, publicKey)
|
||||||
|
unsigned char *content; /* content */
|
||||||
|
unsigned int *contentLen; /* length of content */
|
||||||
|
unsigned char *encodedContent; /* (possibly) encoded content */
|
||||||
|
unsigned int encodedContentLen; /* length of encoded content */
|
||||||
|
unsigned char *encodedSignature; /* encoded signature */
|
||||||
|
unsigned int encodedSignatureLen; /* length of encoded signature */
|
||||||
|
int recode; /* recoding flag */
|
||||||
|
int digestAlgorithm; /* message-digest algorithm */
|
||||||
|
R_RSA_PUBLIC_KEY *publicKey; /* signer's RSA public key */
|
||||||
|
{
|
||||||
|
unsigned char signature[MAX_SIGNATURE_LEN];
|
||||||
|
unsigned int signatureLen;
|
||||||
|
|
||||||
|
if (encodedSignatureLen > MAX_PEM_SIGNATURE_LEN)
|
||||||
|
return (RE_SIGNATURE_ENCODING);
|
||||||
|
|
||||||
|
if (recode) {
|
||||||
|
if (R_DecodePEMBlock
|
||||||
|
(content, contentLen, encodedContent, encodedContentLen))
|
||||||
|
return (RE_CONTENT_ENCODING);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
content = encodedContent;
|
||||||
|
*contentLen = encodedContentLen;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (R_DecodePEMBlock
|
||||||
|
(signature, &signatureLen, encodedSignature, encodedSignatureLen))
|
||||||
|
return (RE_SIGNATURE_ENCODING);
|
||||||
|
|
||||||
|
return (R_VerifyBlockSignature
|
||||||
|
(content, *contentLen, signature, signatureLen, digestAlgorithm,
|
||||||
|
publicKey));
|
||||||
|
}
|
||||||
|
|
||||||
|
int R_VerifyBlockSignature
|
||||||
|
(block, blockLen, signature, signatureLen, digestAlgorithm, publicKey)
|
||||||
|
unsigned char *block; /* block */
|
||||||
|
unsigned int blockLen; /* length of block */
|
||||||
|
unsigned char *signature; /* signature */
|
||||||
|
unsigned int signatureLen; /* length of signature */
|
||||||
|
int digestAlgorithm; /* message-digest algorithm */
|
||||||
|
R_RSA_PUBLIC_KEY *publicKey; /* signer's RSA public key */
|
||||||
|
{
|
||||||
|
R_SIGNATURE_CTX context;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
do {
|
||||||
|
if ((status = R_VerifyInit (&context, digestAlgorithm)) != 0)
|
||||||
|
break;
|
||||||
|
if ((status = R_VerifyUpdate (&context, block, blockLen)) != 0)
|
||||||
|
break;
|
||||||
|
if ((status = R_VerifyFinal (&context, signature, signatureLen, publicKey))
|
||||||
|
!= 0)
|
||||||
|
break;
|
||||||
|
} while (0);
|
||||||
|
|
||||||
|
/* Zeroize sensitive information. */
|
||||||
|
R_memset ((POINTER)&context, 0, sizeof (context));
|
||||||
|
|
||||||
|
return (status);
|
||||||
|
}
|
||||||
|
|
||||||
|
int R_SealPEMBlock
|
||||||
|
(encryptedContent, encryptedContentLen, encryptedKey, encryptedKeyLen,
|
||||||
|
encryptedSignature, encryptedSignatureLen, iv, content, contentLen,
|
||||||
|
digestAlgorithm, publicKey, privateKey, randomStruct)
|
||||||
|
unsigned char *encryptedContent; /* encoded, encrypted content */
|
||||||
|
unsigned int *encryptedContentLen; /* length */
|
||||||
|
unsigned char *encryptedKey; /* encoded, encrypted key */
|
||||||
|
unsigned int *encryptedKeyLen; /* length */
|
||||||
|
unsigned char *encryptedSignature; /* encoded, encrypted signature */
|
||||||
|
unsigned int *encryptedSignatureLen; /* length */
|
||||||
|
unsigned char iv[8]; /* DES initialization vector */
|
||||||
|
unsigned char *content; /* content */
|
||||||
|
unsigned int contentLen; /* length of content */
|
||||||
|
int digestAlgorithm; /* message-digest algorithms */
|
||||||
|
R_RSA_PUBLIC_KEY *publicKey; /* recipient's RSA public key */
|
||||||
|
R_RSA_PRIVATE_KEY *privateKey; /* signer's RSA private key */
|
||||||
|
R_RANDOM_STRUCT *randomStruct; /* random structure */
|
||||||
|
{
|
||||||
|
R_ENVELOPE_CTX context;
|
||||||
|
R_RSA_PUBLIC_KEY *publicKeys[1];
|
||||||
|
int status;
|
||||||
|
unsigned char encryptedKeyBlock[MAX_ENCRYPTED_KEY_LEN],
|
||||||
|
signature[MAX_SIGNATURE_LEN], *encryptedKeys[1];
|
||||||
|
unsigned int signatureLen, encryptedKeyBlockLen;
|
||||||
|
|
||||||
|
do {
|
||||||
|
if ((status = R_SignBlock
|
||||||
|
(signature, &signatureLen, content, contentLen, digestAlgorithm,
|
||||||
|
privateKey)) != 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
publicKeys[0] = publicKey;
|
||||||
|
encryptedKeys[0] = encryptedKeyBlock;
|
||||||
|
if ((status = R_SealInit
|
||||||
|
(&context, encryptedKeys, &encryptedKeyBlockLen, iv, 1, publicKeys,
|
||||||
|
EA_DES_CBC, randomStruct)) != 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
R_EncodePEMBlock
|
||||||
|
(encryptedKey, encryptedKeyLen, encryptedKeyBlock,
|
||||||
|
encryptedKeyBlockLen);
|
||||||
|
|
||||||
|
EncryptPEMUpdateFinal
|
||||||
|
(&context, encryptedContent, encryptedContentLen, content,
|
||||||
|
contentLen);
|
||||||
|
|
||||||
|
EncryptPEMUpdateFinal
|
||||||
|
(&context, encryptedSignature, encryptedSignatureLen, signature,
|
||||||
|
signatureLen);
|
||||||
|
} while (0);
|
||||||
|
|
||||||
|
/* Zeroize sensitive information.
|
||||||
|
*/
|
||||||
|
R_memset ((POINTER)&context, 0, sizeof (context));
|
||||||
|
R_memset ((POINTER)signature, 0, sizeof (signature));
|
||||||
|
|
||||||
|
return (status);
|
||||||
|
}
|
||||||
|
|
||||||
|
int R_OpenPEMBlock
|
||||||
|
(content, contentLen, encryptedContent, encryptedContentLen, encryptedKey,
|
||||||
|
encryptedKeyLen, encryptedSignature, encryptedSignatureLen,
|
||||||
|
iv, digestAlgorithm, privateKey, publicKey)
|
||||||
|
unsigned char *content; /* content */
|
||||||
|
unsigned int *contentLen; /* length of content */
|
||||||
|
unsigned char *encryptedContent; /* encoded, encrypted content */
|
||||||
|
unsigned int encryptedContentLen; /* length */
|
||||||
|
unsigned char *encryptedKey; /* encoded, encrypted key */
|
||||||
|
unsigned int encryptedKeyLen; /* length */
|
||||||
|
unsigned char *encryptedSignature; /* encoded, encrypted signature */
|
||||||
|
unsigned int encryptedSignatureLen; /* length */
|
||||||
|
unsigned char iv[8]; /* DES initialization vector */
|
||||||
|
int digestAlgorithm; /* message-digest algorithms */
|
||||||
|
R_RSA_PRIVATE_KEY *privateKey; /* recipient's RSA private key */
|
||||||
|
R_RSA_PUBLIC_KEY *publicKey; /* signer's RSA public key */
|
||||||
|
{
|
||||||
|
R_ENVELOPE_CTX context;
|
||||||
|
int status;
|
||||||
|
unsigned char encryptedKeyBlock[MAX_ENCRYPTED_KEY_LEN],
|
||||||
|
signature[MAX_SIGNATURE_LEN];
|
||||||
|
unsigned int encryptedKeyBlockLen, signatureLen;
|
||||||
|
|
||||||
|
if (encryptedKeyLen > MAX_PEM_ENCRYPTED_KEY_LEN)
|
||||||
|
return (RE_KEY_ENCODING);
|
||||||
|
|
||||||
|
if (encryptedSignatureLen > MAX_PEM_ENCRYPTED_SIGNATURE_LEN)
|
||||||
|
return (RE_SIGNATURE_ENCODING);
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (R_DecodePEMBlock
|
||||||
|
(encryptedKeyBlock, &encryptedKeyBlockLen, encryptedKey,
|
||||||
|
encryptedKeyLen) != 0) {
|
||||||
|
status = RE_KEY_ENCODING;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((status = R_OpenInit
|
||||||
|
(&context, EA_DES_CBC, encryptedKeyBlock, encryptedKeyBlockLen,
|
||||||
|
iv, privateKey)) != 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if ((status = DecryptPEMUpdateFinal
|
||||||
|
(&context, content, contentLen, encryptedContent,
|
||||||
|
encryptedContentLen)) != 0) {
|
||||||
|
if ((status == RE_LEN || status == RE_ENCODING))
|
||||||
|
status = RE_CONTENT_ENCODING;
|
||||||
|
else
|
||||||
|
status = RE_KEY;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((status = DecryptPEMUpdateFinal
|
||||||
|
(&context, signature, &signatureLen, encryptedSignature,
|
||||||
|
encryptedSignatureLen))) {
|
||||||
|
if ((status == RE_LEN || status == RE_ENCODING))
|
||||||
|
status = RE_SIGNATURE_ENCODING;
|
||||||
|
else
|
||||||
|
status = RE_KEY;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((status = R_VerifyBlockSignature
|
||||||
|
(content, *contentLen, signature, signatureLen, digestAlgorithm,
|
||||||
|
publicKey)) != 0)
|
||||||
|
break;
|
||||||
|
} while (0);
|
||||||
|
|
||||||
|
/* Zeroize sensitive information.
|
||||||
|
*/
|
||||||
|
R_memset ((POINTER)&context, 0, sizeof (context));
|
||||||
|
R_memset ((POINTER)signature, 0, sizeof (signature));
|
||||||
|
|
||||||
|
return (status);
|
||||||
|
}
|
||||||
|
|
||||||
|
int R_DigestBlock (digest, digestLen, block, blockLen, digestAlgorithm)
|
||||||
|
unsigned char *digest; /* message digest */
|
||||||
|
unsigned int *digestLen; /* length of message digest */
|
||||||
|
unsigned char *block; /* block */
|
||||||
|
unsigned int blockLen; /* length of block */
|
||||||
|
int digestAlgorithm; /* message-digest algorithm */
|
||||||
|
{
|
||||||
|
R_DIGEST_CTX context;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
do {
|
||||||
|
if ((status = R_DigestInit (&context, digestAlgorithm)) != 0)
|
||||||
|
break;
|
||||||
|
if ((status = R_DigestUpdate (&context, block, blockLen)) != 0)
|
||||||
|
break;
|
||||||
|
if ((status = R_DigestFinal (&context, digest, digestLen)) != 0)
|
||||||
|
break;
|
||||||
|
} while (0);
|
||||||
|
|
||||||
|
/* Zeroize sensitive information. */
|
||||||
|
R_memset ((POINTER)&context, 0, sizeof (context));
|
||||||
|
|
||||||
|
return (status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Assumes digestAlgorithm is DA_MD2 or DA_MD5 and digest length is 16.
|
||||||
|
*/
|
||||||
|
static void R_EncodeDigestInfo (digestInfo, digestAlgorithm, digest)
|
||||||
|
unsigned char *digestInfo; /* DigestInfo encoding */
|
||||||
|
int digestAlgorithm; /* message-digest algorithm */
|
||||||
|
unsigned char *digest; /* message digest */
|
||||||
|
{
|
||||||
|
R_memcpy
|
||||||
|
((POINTER)digestInfo, (POINTER)DIGEST_INFO_A, DIGEST_INFO_A_LEN);
|
||||||
|
|
||||||
|
digestInfo[DIGEST_INFO_A_LEN] =
|
||||||
|
(digestAlgorithm == DA_MD2) ? (unsigned char)2 : (unsigned char)5;
|
||||||
|
|
||||||
|
R_memcpy
|
||||||
|
((POINTER)&digestInfo[DIGEST_INFO_A_LEN + 1], (POINTER)DIGEST_INFO_B,
|
||||||
|
DIGEST_INFO_B_LEN);
|
||||||
|
|
||||||
|
R_memcpy
|
||||||
|
((POINTER)&digestInfo[DIGEST_INFO_A_LEN + 1 + DIGEST_INFO_B_LEN],
|
||||||
|
(POINTER)digest, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Call SealUpdate and SealFinal on the input and ASCII recode.
|
||||||
|
*/
|
||||||
|
static void EncryptPEMUpdateFinal
|
||||||
|
(context, output, outputLen, input, inputLen)
|
||||||
|
R_ENVELOPE_CTX *context;
|
||||||
|
unsigned char *output; /* encrypted, encoded block */
|
||||||
|
unsigned int *outputLen; /* length of output */
|
||||||
|
unsigned char *input; /* block to encrypt */
|
||||||
|
unsigned int inputLen; /* length */
|
||||||
|
{
|
||||||
|
unsigned char encryptedPart[24];
|
||||||
|
unsigned int i, lastPartLen, tempLen, len;
|
||||||
|
|
||||||
|
/* Choose a buffer size of 24 bytes to hold the temporary encrypted output
|
||||||
|
which will be encoded.
|
||||||
|
Encrypt and encode as many 24-byte blocks as possible.
|
||||||
|
*/
|
||||||
|
for (i = 0; i < inputLen / 24; ++i) {
|
||||||
|
/* Assume part out length will equal part in length since it is
|
||||||
|
a multiple of 8. Also assume no error output. */
|
||||||
|
R_SealUpdate (context, encryptedPart, &tempLen, &input[24*i], 24);
|
||||||
|
|
||||||
|
/* len is always 32 */
|
||||||
|
R_EncodePEMBlock (&output[32*i], &tempLen, encryptedPart, 24);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Encrypt the last part into encryptedPart.
|
||||||
|
*/
|
||||||
|
R_SealUpdate
|
||||||
|
(context, encryptedPart, &lastPartLen, &input[24*i], inputLen - 24*i);
|
||||||
|
R_SealFinal (context, encryptedPart + lastPartLen, &len);
|
||||||
|
lastPartLen += len;
|
||||||
|
|
||||||
|
R_EncodePEMBlock (&output[32*i], &len, encryptedPart, lastPartLen);
|
||||||
|
*outputLen = 32*i + len;
|
||||||
|
|
||||||
|
/* Zeroize sensitive information.
|
||||||
|
*/
|
||||||
|
R_memset ((POINTER)encryptedPart, 0, sizeof (encryptedPart));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int DecryptPEMUpdateFinal (context, output, outputLen, input, inputLen)
|
||||||
|
R_ENVELOPE_CTX *context;
|
||||||
|
unsigned char *output; /* decoded, decrypted block */
|
||||||
|
unsigned int *outputLen; /* length of output */
|
||||||
|
unsigned char *input; /* encrypted, encoded block */
|
||||||
|
unsigned int inputLen; /* length */
|
||||||
|
{
|
||||||
|
int status = 0;
|
||||||
|
unsigned char encryptedPart[24];
|
||||||
|
unsigned int i, len;
|
||||||
|
|
||||||
|
do {
|
||||||
|
/* Choose a buffer size of 24 bytes to hold the temporary decoded output
|
||||||
|
which will be decrypted.
|
||||||
|
Decode and decrypt as many 32-byte input blocks as possible.
|
||||||
|
*/
|
||||||
|
*outputLen = 0;
|
||||||
|
for (i = 0; i < inputLen/32; i++) {
|
||||||
|
/* len is always 24 */
|
||||||
|
if ((status = R_DecodePEMBlock
|
||||||
|
(encryptedPart, &len, &input[32*i], 32)) != 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Excpect no error return */
|
||||||
|
R_OpenUpdate (context, output, &len, encryptedPart, 24);
|
||||||
|
output += len;
|
||||||
|
*outputLen += len;
|
||||||
|
}
|
||||||
|
if (status)
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Decode the last part */
|
||||||
|
if ((status = R_DecodePEMBlock
|
||||||
|
(encryptedPart, &len, &input[32*i], inputLen - 32*i)) != 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Decrypt the last part.
|
||||||
|
*/
|
||||||
|
R_OpenUpdate (context, output, &len, encryptedPart, len);
|
||||||
|
output += len;
|
||||||
|
*outputLen += len;
|
||||||
|
if ((status = R_OpenFinal (context, output, &len)) != 0)
|
||||||
|
break;
|
||||||
|
*outputLen += len;
|
||||||
|
} while (0);
|
||||||
|
|
||||||
|
/* Zeroize sensitive information.
|
||||||
|
*/
|
||||||
|
R_memset ((POINTER)&context, 0, sizeof (context));
|
||||||
|
R_memset ((POINTER)encryptedPart, 0, sizeof (encryptedPart));
|
||||||
|
|
||||||
|
return (status);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int CipherInit (context, encryptionAlgorithm, key, iv, encrypt)
|
||||||
|
R_ENVELOPE_CTX *context;
|
||||||
|
int encryptionAlgorithm;
|
||||||
|
unsigned char *key; /* DES key */
|
||||||
|
unsigned char *iv; /* DES initialization vector */
|
||||||
|
int encrypt; /* encrypt flag (1 = encrypt, 0 = decrypt) */
|
||||||
|
{
|
||||||
|
switch (encryptionAlgorithm) {
|
||||||
|
case EA_DES_CBC:
|
||||||
|
DES_CBCInit (&context->cipherContext.des, key, iv, encrypt);
|
||||||
|
return (0);
|
||||||
|
case EA_DESX_CBC:
|
||||||
|
DESX_CBCInit (&context->cipherContext.desx, key, iv, encrypt);
|
||||||
|
return (0);
|
||||||
|
case EA_DES_EDE2_CBC:
|
||||||
|
case EA_DES_EDE3_CBC:
|
||||||
|
DES3_CBCInit (&context->cipherContext.des3, key, iv, encrypt);
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
default:
|
||||||
|
return (RE_ENCRYPTION_ALGORITHM);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Assume len is a multiple of 8.
|
||||||
|
*/
|
||||||
|
static void CipherUpdate (context, output, input, len)
|
||||||
|
R_ENVELOPE_CTX *context;
|
||||||
|
unsigned char *output; /* output block */
|
||||||
|
unsigned char *input; /* input block */
|
||||||
|
unsigned int len; /* length of input and output blocks */
|
||||||
|
{
|
||||||
|
if (context->encryptionAlgorithm == EA_DES_CBC)
|
||||||
|
DES_CBCUpdate (&context->cipherContext.des, output, input, len);
|
||||||
|
else if (context->encryptionAlgorithm == EA_DESX_CBC)
|
||||||
|
DESX_CBCUpdate (&context->cipherContext.desx, output, input, len);
|
||||||
|
else
|
||||||
|
DES3_CBCUpdate (&context->cipherContext.des3, output, input, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void CipherRestart (context)
|
||||||
|
R_ENVELOPE_CTX *context;
|
||||||
|
{
|
||||||
|
if (context->encryptionAlgorithm == EA_DES_CBC)
|
||||||
|
DES_CBCRestart (&context->cipherContext.des);
|
||||||
|
else if (context->encryptionAlgorithm == EA_DESX_CBC)
|
||||||
|
DESX_CBCRestart (&context->cipherContext.desx);
|
||||||
|
else
|
||||||
|
DES3_CBCRestart (&context->cipherContext.des3);
|
||||||
|
}
|
182
lib/rsaref/r_keygen.c
Normal file
182
lib/rsaref/r_keygen.c
Normal file
|
@ -0,0 +1,182 @@
|
||||||
|
/* R_KEYGEN.C - key-pair generation for RSAREF
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Copyright (C) RSA Laboratories, a division of RSA Data Security,
|
||||||
|
Inc., created 1991. All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "global.h"
|
||||||
|
#include "rsaref.h"
|
||||||
|
#include "r_random.h"
|
||||||
|
#include "nn.h"
|
||||||
|
#include "prime.h"
|
||||||
|
|
||||||
|
static int RSAFilter PROTO_LIST
|
||||||
|
((NN_DIGIT *, unsigned int, NN_DIGIT *, unsigned int));
|
||||||
|
static int RelativelyPrime PROTO_LIST
|
||||||
|
((NN_DIGIT *, unsigned int, NN_DIGIT *, unsigned int));
|
||||||
|
|
||||||
|
/* Generates an RSA key pair with a given length and public exponent.
|
||||||
|
*/
|
||||||
|
int R_GeneratePEMKeys (publicKey, privateKey, protoKey, randomStruct)
|
||||||
|
R_RSA_PUBLIC_KEY *publicKey; /* new RSA public key */
|
||||||
|
R_RSA_PRIVATE_KEY *privateKey; /* new RSA private key */
|
||||||
|
R_RSA_PROTO_KEY *protoKey; /* RSA prototype key */
|
||||||
|
R_RANDOM_STRUCT *randomStruct; /* random structure */
|
||||||
|
{
|
||||||
|
NN_DIGIT d[MAX_NN_DIGITS], dP[MAX_NN_DIGITS], dQ[MAX_NN_DIGITS],
|
||||||
|
e[MAX_NN_DIGITS], n[MAX_NN_DIGITS], p[MAX_NN_DIGITS], phiN[MAX_NN_DIGITS],
|
||||||
|
pMinus1[MAX_NN_DIGITS], q[MAX_NN_DIGITS], qInv[MAX_NN_DIGITS],
|
||||||
|
qMinus1[MAX_NN_DIGITS], t[MAX_NN_DIGITS], u[MAX_NN_DIGITS],
|
||||||
|
v[MAX_NN_DIGITS];
|
||||||
|
int status = 0;
|
||||||
|
unsigned int nDigits, pBits, pDigits, qBits;
|
||||||
|
|
||||||
|
if ((protoKey->bits < MIN_RSA_MODULUS_BITS) ||
|
||||||
|
(protoKey->bits > MAX_RSA_MODULUS_BITS))
|
||||||
|
return (RE_MODULUS_LEN);
|
||||||
|
nDigits = (protoKey->bits + NN_DIGIT_BITS - 1) / NN_DIGIT_BITS;
|
||||||
|
pDigits = (nDigits + 1) / 2;
|
||||||
|
pBits = (protoKey->bits + 1) / 2;
|
||||||
|
qBits = protoKey->bits - pBits;
|
||||||
|
|
||||||
|
/* NOTE: for 65537, this assumes NN_DIGIT is at least 17 bits. */
|
||||||
|
NN_ASSIGN_DIGIT
|
||||||
|
(e, protoKey->useFermat4 ? (NN_DIGIT)65537 : (NN_DIGIT)3, nDigits);
|
||||||
|
|
||||||
|
/* Generate prime p between 3*2^(pBits-2) and 2^pBits-1, searching
|
||||||
|
in steps of 2, until one satisfies gcd (p-1, e) = 1.
|
||||||
|
*/
|
||||||
|
NN_Assign2Exp (t, pBits-1, pDigits);
|
||||||
|
NN_Assign2Exp (u, pBits-2, pDigits);
|
||||||
|
NN_Add (t, t, u, pDigits);
|
||||||
|
NN_ASSIGN_DIGIT (v, 1, pDigits);
|
||||||
|
NN_Sub (v, t, v, pDigits);
|
||||||
|
NN_Add (u, u, v, pDigits);
|
||||||
|
NN_ASSIGN_DIGIT (v, 2, pDigits);
|
||||||
|
do {
|
||||||
|
if ((status = GeneratePrime (p, t, u, v, pDigits, randomStruct)))
|
||||||
|
return (status);
|
||||||
|
}
|
||||||
|
while (! RSAFilter (p, pDigits, e, 1));
|
||||||
|
|
||||||
|
/* Generate prime q between 3*2^(qBits-2) and 2^qBits-1, searching
|
||||||
|
in steps of 2, until one satisfies gcd (q-1, e) = 1.
|
||||||
|
*/
|
||||||
|
NN_Assign2Exp (t, qBits-1, pDigits);
|
||||||
|
NN_Assign2Exp (u, qBits-2, pDigits);
|
||||||
|
NN_Add (t, t, u, pDigits);
|
||||||
|
NN_ASSIGN_DIGIT (v, 1, pDigits);
|
||||||
|
NN_Sub (v, t, v, pDigits);
|
||||||
|
NN_Add (u, u, v, pDigits);
|
||||||
|
NN_ASSIGN_DIGIT (v, 2, pDigits);
|
||||||
|
do {
|
||||||
|
if ((status = GeneratePrime (q, t, u, v, pDigits, randomStruct)))
|
||||||
|
return (status);
|
||||||
|
}
|
||||||
|
while (! RSAFilter (q, pDigits, e, 1));
|
||||||
|
|
||||||
|
/* Sort so that p > q. (p = q case is extremely unlikely.)
|
||||||
|
*/
|
||||||
|
if (NN_Cmp (p, q, pDigits) < 0) {
|
||||||
|
NN_Assign (t, p, pDigits);
|
||||||
|
NN_Assign (p, q, pDigits);
|
||||||
|
NN_Assign (q, t, pDigits);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Compute n = pq, qInv = q^{-1} mod p, d = e^{-1} mod (p-1)(q-1),
|
||||||
|
dP = d mod p-1, dQ = d mod q-1.
|
||||||
|
*/
|
||||||
|
NN_Mult (n, p, q, pDigits);
|
||||||
|
NN_ModInv (qInv, q, p, pDigits);
|
||||||
|
|
||||||
|
NN_ASSIGN_DIGIT (t, 1, pDigits);
|
||||||
|
NN_Sub (pMinus1, p, t, pDigits);
|
||||||
|
NN_Sub (qMinus1, q, t, pDigits);
|
||||||
|
NN_Mult (phiN, pMinus1, qMinus1, pDigits);
|
||||||
|
|
||||||
|
NN_ModInv (d, e, phiN, nDigits);
|
||||||
|
NN_Mod (dP, d, nDigits, pMinus1, pDigits);
|
||||||
|
NN_Mod (dQ, d, nDigits, qMinus1, pDigits);
|
||||||
|
|
||||||
|
publicKey->bits = privateKey->bits = protoKey->bits;
|
||||||
|
NN_Encode (publicKey->modulus, MAX_RSA_MODULUS_LEN, n, nDigits);
|
||||||
|
NN_Encode (publicKey->exponent, MAX_RSA_MODULUS_LEN, e, 1);
|
||||||
|
R_memcpy
|
||||||
|
((POINTER)privateKey->modulus, (POINTER)publicKey->modulus,
|
||||||
|
MAX_RSA_MODULUS_LEN);
|
||||||
|
R_memcpy
|
||||||
|
((POINTER)privateKey->publicExponent, (POINTER)publicKey->exponent,
|
||||||
|
MAX_RSA_MODULUS_LEN);
|
||||||
|
NN_Encode (privateKey->exponent, MAX_RSA_MODULUS_LEN, d, nDigits);
|
||||||
|
NN_Encode (privateKey->prime[0], MAX_RSA_PRIME_LEN, p, pDigits);
|
||||||
|
NN_Encode (privateKey->prime[1], MAX_RSA_PRIME_LEN, q, pDigits);
|
||||||
|
NN_Encode (privateKey->primeExponent[0], MAX_RSA_PRIME_LEN, dP, pDigits);
|
||||||
|
NN_Encode (privateKey->primeExponent[1], MAX_RSA_PRIME_LEN, dQ, pDigits);
|
||||||
|
NN_Encode (privateKey->coefficient, MAX_RSA_PRIME_LEN, qInv, pDigits);
|
||||||
|
|
||||||
|
/* Zeroize sensitive information.
|
||||||
|
*/
|
||||||
|
R_memset ((POINTER)d, 0, sizeof (d));
|
||||||
|
R_memset ((POINTER)dP, 0, sizeof (dP));
|
||||||
|
R_memset ((POINTER)dQ, 0, sizeof (dQ));
|
||||||
|
R_memset ((POINTER)p, 0, sizeof (p));
|
||||||
|
R_memset ((POINTER)phiN, 0, sizeof (phiN));
|
||||||
|
R_memset ((POINTER)pMinus1, 0, sizeof (pMinus1));
|
||||||
|
R_memset ((POINTER)q, 0, sizeof (q));
|
||||||
|
R_memset ((POINTER)qInv, 0, sizeof (qInv));
|
||||||
|
R_memset ((POINTER)qMinus1, 0, sizeof (qMinus1));
|
||||||
|
R_memset ((POINTER)t, 0, sizeof (t));
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns nonzero iff GCD (a-1, b) = 1.
|
||||||
|
|
||||||
|
Lengths: a[aDigits], b[bDigits].
|
||||||
|
Assumes aDigits < MAX_NN_DIGITS, bDigits < MAX_NN_DIGITS.
|
||||||
|
*/
|
||||||
|
static int RSAFilter (a, aDigits, b, bDigits)
|
||||||
|
NN_DIGIT *a, *b;
|
||||||
|
unsigned int aDigits, bDigits;
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
NN_DIGIT aMinus1[MAX_NN_DIGITS], t[MAX_NN_DIGITS];
|
||||||
|
|
||||||
|
NN_ASSIGN_DIGIT (t, 1, aDigits);
|
||||||
|
NN_Sub (aMinus1, a, t, aDigits);
|
||||||
|
|
||||||
|
status = RelativelyPrime (aMinus1, aDigits, b, bDigits);
|
||||||
|
|
||||||
|
/* Zeroize sensitive information.
|
||||||
|
*/
|
||||||
|
R_memset ((POINTER)aMinus1, 0, sizeof (aMinus1));
|
||||||
|
|
||||||
|
return (status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns nonzero iff a and b are relatively prime.
|
||||||
|
|
||||||
|
Lengths: a[aDigits], b[bDigits].
|
||||||
|
Assumes aDigits >= bDigits, aDigits < MAX_NN_DIGITS.
|
||||||
|
*/
|
||||||
|
static int RelativelyPrime (a, aDigits, b, bDigits)
|
||||||
|
NN_DIGIT *a, *b;
|
||||||
|
unsigned int aDigits, bDigits;
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
NN_DIGIT t[MAX_NN_DIGITS], u[MAX_NN_DIGITS];
|
||||||
|
|
||||||
|
NN_AssignZero (t, aDigits);
|
||||||
|
NN_Assign (t, b, bDigits);
|
||||||
|
NN_Gcd (t, a, t, aDigits);
|
||||||
|
NN_ASSIGN_DIGIT (u, 1, aDigits);
|
||||||
|
|
||||||
|
status = NN_EQUAL (t, u, aDigits);
|
||||||
|
|
||||||
|
/* Zeroize sensitive information.
|
||||||
|
*/
|
||||||
|
R_memset ((POINTER)t, 0, sizeof (t));
|
||||||
|
|
||||||
|
return (status);
|
||||||
|
}
|
111
lib/rsaref/r_random.c
Normal file
111
lib/rsaref/r_random.c
Normal file
|
@ -0,0 +1,111 @@
|
||||||
|
/* R_RANDOM.C - random objects for RSAREF
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Copyright (C) RSA Laboratories, a division of RSA Data Security,
|
||||||
|
Inc., created 1991. All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "global.h"
|
||||||
|
#include "rsaref.h"
|
||||||
|
#include "r_random.h"
|
||||||
|
#include "md5.h"
|
||||||
|
|
||||||
|
#define RANDOM_BYTES_NEEDED 256
|
||||||
|
|
||||||
|
int R_RandomInit (randomStruct)
|
||||||
|
R_RANDOM_STRUCT *randomStruct; /* new random structure */
|
||||||
|
{
|
||||||
|
randomStruct->bytesNeeded = RANDOM_BYTES_NEEDED;
|
||||||
|
R_memset ((POINTER)randomStruct->state, 0, sizeof (randomStruct->state));
|
||||||
|
randomStruct->outputAvailable = 0;
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int R_RandomUpdate (randomStruct, block, blockLen)
|
||||||
|
R_RANDOM_STRUCT *randomStruct; /* random structure */
|
||||||
|
unsigned char *block; /* block of values to mix in */
|
||||||
|
unsigned int blockLen; /* length of block */
|
||||||
|
{
|
||||||
|
MD5_CTX context;
|
||||||
|
unsigned char digest[16];
|
||||||
|
unsigned int i, x;
|
||||||
|
|
||||||
|
MD5Init (&context);
|
||||||
|
MD5Update (&context, block, blockLen);
|
||||||
|
MD5Final (digest, &context);
|
||||||
|
|
||||||
|
/* add digest to state */
|
||||||
|
x = 0;
|
||||||
|
for (i = 0; i < 16; i++) {
|
||||||
|
x += randomStruct->state[15-i] + digest[15-i];
|
||||||
|
randomStruct->state[15-i] = (unsigned char)x;
|
||||||
|
x >>= 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (randomStruct->bytesNeeded < blockLen)
|
||||||
|
randomStruct->bytesNeeded = 0;
|
||||||
|
else
|
||||||
|
randomStruct->bytesNeeded -= blockLen;
|
||||||
|
|
||||||
|
/* Zeroize sensitive information.
|
||||||
|
*/
|
||||||
|
R_memset ((POINTER)digest, 0, sizeof (digest));
|
||||||
|
x = 0;
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int R_GetRandomBytesNeeded (bytesNeeded, randomStruct)
|
||||||
|
unsigned int *bytesNeeded; /* number of mix-in bytes needed */
|
||||||
|
R_RANDOM_STRUCT *randomStruct; /* random structure */
|
||||||
|
{
|
||||||
|
*bytesNeeded = randomStruct->bytesNeeded;
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int R_GenerateBytes (block, blockLen, randomStruct)
|
||||||
|
unsigned char *block; /* block */
|
||||||
|
unsigned int blockLen; /* length of block */
|
||||||
|
R_RANDOM_STRUCT *randomStruct; /* random structure */
|
||||||
|
{
|
||||||
|
MD5_CTX context;
|
||||||
|
unsigned int available, i;
|
||||||
|
|
||||||
|
if (randomStruct->bytesNeeded)
|
||||||
|
return (RE_NEED_RANDOM);
|
||||||
|
|
||||||
|
available = randomStruct->outputAvailable;
|
||||||
|
|
||||||
|
while (blockLen > available) {
|
||||||
|
R_memcpy
|
||||||
|
((POINTER)block, (POINTER)&randomStruct->output[16-available],
|
||||||
|
available);
|
||||||
|
block += available;
|
||||||
|
blockLen -= available;
|
||||||
|
|
||||||
|
/* generate new output */
|
||||||
|
MD5Init (&context);
|
||||||
|
MD5Update (&context, randomStruct->state, 16);
|
||||||
|
MD5Final (randomStruct->output, &context);
|
||||||
|
available = 16;
|
||||||
|
|
||||||
|
/* increment state */
|
||||||
|
for (i = 0; i < 16; i++)
|
||||||
|
if (randomStruct->state[15-i]++)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
R_memcpy
|
||||||
|
((POINTER)block, (POINTER)&randomStruct->output[16-available], blockLen);
|
||||||
|
randomStruct->outputAvailable = available - blockLen;
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void R_RandomFinal (randomStruct)
|
||||||
|
R_RANDOM_STRUCT *randomStruct; /* random structure */
|
||||||
|
{
|
||||||
|
R_memset ((POINTER)randomStruct, 0, sizeof (*randomStruct));
|
||||||
|
}
|
9
lib/rsaref/r_random.h
Normal file
9
lib/rsaref/r_random.h
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
/* R_RANDOM.H - header file for R_RANDOM.C
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Copyright (C) RSA Laboratories, a division of RSA Data Security,
|
||||||
|
Inc., created 1991. All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int R_GenerateBytes PROTO_LIST
|
||||||
|
((unsigned char *, unsigned int, R_RANDOM_STRUCT *));
|
39
lib/rsaref/r_stdlib.c
Normal file
39
lib/rsaref/r_stdlib.c
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
/* R_STDLIB.C - platform-specific C library routines for RSAREF
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Copyright (C) RSA Laboratories, a division of RSA Data Security,
|
||||||
|
Inc., created 1991. All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include "global.h"
|
||||||
|
#include "rsaref.h"
|
||||||
|
|
||||||
|
void R_memset (output, value, len)
|
||||||
|
POINTER output; /* output block */
|
||||||
|
int value; /* value */
|
||||||
|
unsigned int len; /* length of block */
|
||||||
|
{
|
||||||
|
if (len)
|
||||||
|
memset (output, value, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
void R_memcpy (output, input, len)
|
||||||
|
POINTER output; /* output block */
|
||||||
|
POINTER input; /* input block */
|
||||||
|
unsigned int len; /* length of blocks */
|
||||||
|
{
|
||||||
|
if (len)
|
||||||
|
memcpy (output, input, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
int R_memcmp (firstBlock, secondBlock, len)
|
||||||
|
POINTER firstBlock; /* first block */
|
||||||
|
POINTER secondBlock; /* second block */
|
||||||
|
unsigned int len; /* length of blocks */
|
||||||
|
{
|
||||||
|
if (len)
|
||||||
|
return (memcmp (firstBlock, secondBlock, len));
|
||||||
|
else
|
||||||
|
return (0);
|
||||||
|
}
|
324
lib/rsaref/rsa.c
Normal file
324
lib/rsaref/rsa.c
Normal file
|
@ -0,0 +1,324 @@
|
||||||
|
/* RSA.C - RSA routines for RSAREF
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Copyright (C) RSA Laboratories, a division of RSA Data Security,
|
||||||
|
Inc., created 1991. All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "global.h"
|
||||||
|
#include "rsaref.h"
|
||||||
|
#include "r_random.h"
|
||||||
|
#include "rsa.h"
|
||||||
|
#include "nn.h"
|
||||||
|
|
||||||
|
static int RSAPublicBlock PROTO_LIST
|
||||||
|
((unsigned char *, unsigned int *, unsigned char *, unsigned int,
|
||||||
|
R_RSA_PUBLIC_KEY *));
|
||||||
|
static int RSAPrivateBlock PROTO_LIST
|
||||||
|
((unsigned char *, unsigned int *, unsigned char *, unsigned int,
|
||||||
|
R_RSA_PRIVATE_KEY *));
|
||||||
|
|
||||||
|
/* RSA public-key encryption, according to PKCS #1.
|
||||||
|
*/
|
||||||
|
int RSAPublicEncrypt
|
||||||
|
(output, outputLen, input, inputLen, publicKey, randomStruct)
|
||||||
|
unsigned char *output; /* output block */
|
||||||
|
unsigned int *outputLen; /* length of output block */
|
||||||
|
unsigned char *input; /* input block */
|
||||||
|
unsigned int inputLen; /* length of input block */
|
||||||
|
R_RSA_PUBLIC_KEY *publicKey; /* RSA public key */
|
||||||
|
R_RANDOM_STRUCT *randomStruct; /* random structure */
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
unsigned char byte, pkcsBlock[MAX_RSA_MODULUS_LEN];
|
||||||
|
unsigned int i, modulusLen;
|
||||||
|
|
||||||
|
modulusLen = (publicKey->bits + 7) / 8;
|
||||||
|
if (inputLen + 11 > modulusLen)
|
||||||
|
return (RE_LEN);
|
||||||
|
|
||||||
|
pkcsBlock[0] = 0;
|
||||||
|
/* block type 2 */
|
||||||
|
pkcsBlock[1] = 2;
|
||||||
|
|
||||||
|
for (i = 2; i < modulusLen - inputLen - 1; i++) {
|
||||||
|
/* Find nonzero random byte.
|
||||||
|
*/
|
||||||
|
do {
|
||||||
|
R_GenerateBytes (&byte, 1, randomStruct);
|
||||||
|
} while (byte == 0);
|
||||||
|
pkcsBlock[i] = byte;
|
||||||
|
}
|
||||||
|
/* separator */
|
||||||
|
pkcsBlock[i++] = 0;
|
||||||
|
|
||||||
|
R_memcpy ((POINTER)&pkcsBlock[i], (POINTER)input, inputLen);
|
||||||
|
|
||||||
|
status = RSAPublicBlock
|
||||||
|
(output, outputLen, pkcsBlock, modulusLen, publicKey);
|
||||||
|
|
||||||
|
/* Zeroize sensitive information.
|
||||||
|
*/
|
||||||
|
byte = 0;
|
||||||
|
R_memset ((POINTER)pkcsBlock, 0, sizeof (pkcsBlock));
|
||||||
|
|
||||||
|
return (status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* RSA public-key decryption, according to PKCS #1.
|
||||||
|
*/
|
||||||
|
int RSAPublicDecrypt (output, outputLen, input, inputLen, publicKey)
|
||||||
|
unsigned char *output; /* output block */
|
||||||
|
unsigned int *outputLen; /* length of output block */
|
||||||
|
unsigned char *input; /* input block */
|
||||||
|
unsigned int inputLen; /* length of input block */
|
||||||
|
R_RSA_PUBLIC_KEY *publicKey; /* RSA public key */
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
unsigned char pkcsBlock[MAX_RSA_MODULUS_LEN];
|
||||||
|
unsigned int i, modulusLen, pkcsBlockLen;
|
||||||
|
|
||||||
|
modulusLen = (publicKey->bits + 7) / 8;
|
||||||
|
if (inputLen > modulusLen)
|
||||||
|
return (RE_LEN);
|
||||||
|
|
||||||
|
if ((status = RSAPublicBlock
|
||||||
|
(pkcsBlock, &pkcsBlockLen, input, inputLen, publicKey)))
|
||||||
|
return (status);
|
||||||
|
|
||||||
|
if (pkcsBlockLen != modulusLen)
|
||||||
|
return (RE_LEN);
|
||||||
|
|
||||||
|
/* Require block type 1.
|
||||||
|
*/
|
||||||
|
if ((pkcsBlock[0] != 0) || (pkcsBlock[1] != 1))
|
||||||
|
return (RE_DATA);
|
||||||
|
|
||||||
|
for (i = 2; i < modulusLen-1; i++)
|
||||||
|
if (pkcsBlock[i] != 0xff)
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* separator */
|
||||||
|
if (pkcsBlock[i++] != 0)
|
||||||
|
return (RE_DATA);
|
||||||
|
|
||||||
|
*outputLen = modulusLen - i;
|
||||||
|
|
||||||
|
if (*outputLen + 11 > modulusLen)
|
||||||
|
return (RE_DATA);
|
||||||
|
|
||||||
|
R_memcpy ((POINTER)output, (POINTER)&pkcsBlock[i], *outputLen);
|
||||||
|
|
||||||
|
/* Zeroize potentially sensitive information.
|
||||||
|
*/
|
||||||
|
R_memset ((POINTER)pkcsBlock, 0, sizeof (pkcsBlock));
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* RSA private-key encryption, according to PKCS #1.
|
||||||
|
*/
|
||||||
|
int RSAPrivateEncrypt (output, outputLen, input, inputLen, privateKey)
|
||||||
|
unsigned char *output; /* output block */
|
||||||
|
unsigned int *outputLen; /* length of output block */
|
||||||
|
unsigned char *input; /* input block */
|
||||||
|
unsigned int inputLen; /* length of input block */
|
||||||
|
R_RSA_PRIVATE_KEY *privateKey; /* RSA private key */
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
unsigned char pkcsBlock[MAX_RSA_MODULUS_LEN];
|
||||||
|
unsigned int i, modulusLen;
|
||||||
|
|
||||||
|
modulusLen = (privateKey->bits + 7) / 8;
|
||||||
|
if (inputLen + 11 > modulusLen)
|
||||||
|
return (RE_LEN);
|
||||||
|
|
||||||
|
pkcsBlock[0] = 0;
|
||||||
|
/* block type 1 */
|
||||||
|
pkcsBlock[1] = 1;
|
||||||
|
|
||||||
|
for (i = 2; i < modulusLen - inputLen - 1; i++)
|
||||||
|
pkcsBlock[i] = 0xff;
|
||||||
|
|
||||||
|
/* separator */
|
||||||
|
pkcsBlock[i++] = 0;
|
||||||
|
|
||||||
|
R_memcpy ((POINTER)&pkcsBlock[i], (POINTER)input, inputLen);
|
||||||
|
|
||||||
|
status = RSAPrivateBlock
|
||||||
|
(output, outputLen, pkcsBlock, modulusLen, privateKey);
|
||||||
|
|
||||||
|
/* Zeroize potentially sensitive information.
|
||||||
|
*/
|
||||||
|
R_memset ((POINTER)pkcsBlock, 0, sizeof (pkcsBlock));
|
||||||
|
|
||||||
|
return (status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* RSA private-key decryption, according to PKCS #1.
|
||||||
|
*/
|
||||||
|
int RSAPrivateDecrypt (output, outputLen, input, inputLen, privateKey)
|
||||||
|
unsigned char *output; /* output block */
|
||||||
|
unsigned int *outputLen; /* length of output block */
|
||||||
|
unsigned char *input; /* input block */
|
||||||
|
unsigned int inputLen; /* length of input block */
|
||||||
|
R_RSA_PRIVATE_KEY *privateKey; /* RSA private key */
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
unsigned char pkcsBlock[MAX_RSA_MODULUS_LEN];
|
||||||
|
unsigned int i, modulusLen, pkcsBlockLen;
|
||||||
|
|
||||||
|
modulusLen = (privateKey->bits + 7) / 8;
|
||||||
|
if (inputLen > modulusLen)
|
||||||
|
return (RE_LEN);
|
||||||
|
|
||||||
|
if ((status = RSAPrivateBlock
|
||||||
|
(pkcsBlock, &pkcsBlockLen, input, inputLen, privateKey)))
|
||||||
|
return (status);
|
||||||
|
|
||||||
|
if (pkcsBlockLen != modulusLen)
|
||||||
|
return (RE_LEN);
|
||||||
|
|
||||||
|
/* Require block type 2.
|
||||||
|
*/
|
||||||
|
if ((pkcsBlock[0] != 0) || (pkcsBlock[1] != 2))
|
||||||
|
return (RE_DATA);
|
||||||
|
|
||||||
|
for (i = 2; i < modulusLen-1; i++)
|
||||||
|
/* separator */
|
||||||
|
if (pkcsBlock[i] == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
i++;
|
||||||
|
if (i >= modulusLen)
|
||||||
|
return (RE_DATA);
|
||||||
|
|
||||||
|
*outputLen = modulusLen - i;
|
||||||
|
|
||||||
|
if (*outputLen + 11 > modulusLen)
|
||||||
|
return (RE_DATA);
|
||||||
|
|
||||||
|
R_memcpy ((POINTER)output, (POINTER)&pkcsBlock[i], *outputLen);
|
||||||
|
|
||||||
|
/* Zeroize sensitive information.
|
||||||
|
*/
|
||||||
|
R_memset ((POINTER)pkcsBlock, 0, sizeof (pkcsBlock));
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Raw RSA public-key operation. Output has same length as modulus.
|
||||||
|
|
||||||
|
Assumes inputLen < length of modulus.
|
||||||
|
Requires input < modulus.
|
||||||
|
*/
|
||||||
|
static int RSAPublicBlock (output, outputLen, input, inputLen, publicKey)
|
||||||
|
unsigned char *output; /* output block */
|
||||||
|
unsigned int *outputLen; /* length of output block */
|
||||||
|
unsigned char *input; /* input block */
|
||||||
|
unsigned int inputLen; /* length of input block */
|
||||||
|
R_RSA_PUBLIC_KEY *publicKey; /* RSA public key */
|
||||||
|
{
|
||||||
|
NN_DIGIT c[MAX_NN_DIGITS], e[MAX_NN_DIGITS], m[MAX_NN_DIGITS],
|
||||||
|
n[MAX_NN_DIGITS];
|
||||||
|
unsigned int eDigits, nDigits;
|
||||||
|
|
||||||
|
NN_Decode (m, MAX_NN_DIGITS, input, inputLen);
|
||||||
|
NN_Decode (n, MAX_NN_DIGITS, publicKey->modulus, MAX_RSA_MODULUS_LEN);
|
||||||
|
NN_Decode (e, MAX_NN_DIGITS, publicKey->exponent, MAX_RSA_MODULUS_LEN);
|
||||||
|
nDigits = NN_Digits (n, MAX_NN_DIGITS);
|
||||||
|
eDigits = NN_Digits (e, MAX_NN_DIGITS);
|
||||||
|
|
||||||
|
if (NN_Cmp (m, n, nDigits) >= 0)
|
||||||
|
return (RE_DATA);
|
||||||
|
|
||||||
|
/* Compute c = m^e mod n.
|
||||||
|
*/
|
||||||
|
NN_ModExp (c, m, e, eDigits, n, nDigits);
|
||||||
|
|
||||||
|
*outputLen = (publicKey->bits + 7) / 8;
|
||||||
|
NN_Encode (output, *outputLen, c, nDigits);
|
||||||
|
|
||||||
|
/* Zeroize sensitive information.
|
||||||
|
*/
|
||||||
|
R_memset ((POINTER)c, 0, sizeof (c));
|
||||||
|
R_memset ((POINTER)m, 0, sizeof (m));
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Raw RSA private-key operation. Output has same length as modulus.
|
||||||
|
|
||||||
|
Assumes inputLen < length of modulus.
|
||||||
|
Requires input < modulus.
|
||||||
|
*/
|
||||||
|
static int RSAPrivateBlock (output, outputLen, input, inputLen, privateKey)
|
||||||
|
unsigned char *output; /* output block */
|
||||||
|
unsigned int *outputLen; /* length of output block */
|
||||||
|
unsigned char *input; /* input block */
|
||||||
|
unsigned int inputLen; /* length of input block */
|
||||||
|
R_RSA_PRIVATE_KEY *privateKey; /* RSA private key */
|
||||||
|
{
|
||||||
|
NN_DIGIT c[MAX_NN_DIGITS], cP[MAX_NN_DIGITS], cQ[MAX_NN_DIGITS],
|
||||||
|
dP[MAX_NN_DIGITS], dQ[MAX_NN_DIGITS], mP[MAX_NN_DIGITS],
|
||||||
|
mQ[MAX_NN_DIGITS], n[MAX_NN_DIGITS], p[MAX_NN_DIGITS], q[MAX_NN_DIGITS],
|
||||||
|
qInv[MAX_NN_DIGITS], t[MAX_NN_DIGITS];
|
||||||
|
unsigned int cDigits, nDigits, pDigits;
|
||||||
|
|
||||||
|
NN_Decode (c, MAX_NN_DIGITS, input, inputLen);
|
||||||
|
NN_Decode (n, MAX_NN_DIGITS, privateKey->modulus, MAX_RSA_MODULUS_LEN);
|
||||||
|
NN_Decode (p, MAX_NN_DIGITS, privateKey->prime[0], MAX_RSA_PRIME_LEN);
|
||||||
|
NN_Decode (q, MAX_NN_DIGITS, privateKey->prime[1], MAX_RSA_PRIME_LEN);
|
||||||
|
NN_Decode
|
||||||
|
(dP, MAX_NN_DIGITS, privateKey->primeExponent[0], MAX_RSA_PRIME_LEN);
|
||||||
|
NN_Decode
|
||||||
|
(dQ, MAX_NN_DIGITS, privateKey->primeExponent[1], MAX_RSA_PRIME_LEN);
|
||||||
|
NN_Decode (qInv, MAX_NN_DIGITS, privateKey->coefficient, MAX_RSA_PRIME_LEN);
|
||||||
|
cDigits = NN_Digits (c, MAX_NN_DIGITS);
|
||||||
|
nDigits = NN_Digits (n, MAX_NN_DIGITS);
|
||||||
|
pDigits = NN_Digits (p, MAX_NN_DIGITS);
|
||||||
|
|
||||||
|
if (NN_Cmp (c, n, nDigits) >= 0)
|
||||||
|
return (RE_DATA);
|
||||||
|
|
||||||
|
/* Compute mP = cP^dP mod p and mQ = cQ^dQ mod q. (Assumes q has
|
||||||
|
length at most pDigits, i.e., p > q.)
|
||||||
|
*/
|
||||||
|
NN_Mod (cP, c, cDigits, p, pDigits);
|
||||||
|
NN_Mod (cQ, c, cDigits, q, pDigits);
|
||||||
|
NN_ModExp (mP, cP, dP, pDigits, p, pDigits);
|
||||||
|
NN_AssignZero (mQ, nDigits);
|
||||||
|
NN_ModExp (mQ, cQ, dQ, pDigits, q, pDigits);
|
||||||
|
|
||||||
|
/* Chinese Remainder Theorem:
|
||||||
|
m = ((((mP - mQ) mod p) * qInv) mod p) * q + mQ.
|
||||||
|
*/
|
||||||
|
if (NN_Cmp (mP, mQ, pDigits) >= 0)
|
||||||
|
NN_Sub (t, mP, mQ, pDigits);
|
||||||
|
else {
|
||||||
|
NN_Sub (t, mQ, mP, pDigits);
|
||||||
|
NN_Sub (t, p, t, pDigits);
|
||||||
|
}
|
||||||
|
NN_ModMult (t, t, qInv, p, pDigits);
|
||||||
|
NN_Mult (t, t, q, pDigits);
|
||||||
|
NN_Add (t, t, mQ, nDigits);
|
||||||
|
|
||||||
|
*outputLen = (privateKey->bits + 7) / 8;
|
||||||
|
NN_Encode (output, *outputLen, t, nDigits);
|
||||||
|
|
||||||
|
/* Zeroize sensitive information.
|
||||||
|
*/
|
||||||
|
R_memset ((POINTER)c, 0, sizeof (c));
|
||||||
|
R_memset ((POINTER)cP, 0, sizeof (cP));
|
||||||
|
R_memset ((POINTER)cQ, 0, sizeof (cQ));
|
||||||
|
R_memset ((POINTER)dP, 0, sizeof (dP));
|
||||||
|
R_memset ((POINTER)dQ, 0, sizeof (dQ));
|
||||||
|
R_memset ((POINTER)mP, 0, sizeof (mP));
|
||||||
|
R_memset ((POINTER)mQ, 0, sizeof (mQ));
|
||||||
|
R_memset ((POINTER)p, 0, sizeof (p));
|
||||||
|
R_memset ((POINTER)q, 0, sizeof (q));
|
||||||
|
R_memset ((POINTER)qInv, 0, sizeof (qInv));
|
||||||
|
R_memset ((POINTER)t, 0, sizeof (t));
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
19
lib/rsaref/rsa.h
Normal file
19
lib/rsaref/rsa.h
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
/* RSA.H - header file for RSA.C
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Copyright (C) RSA Laboratories, a division of RSA Data Security,
|
||||||
|
Inc., created 1991. All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int RSAPublicEncrypt PROTO_LIST
|
||||||
|
((unsigned char *, unsigned int *, unsigned char *, unsigned int,
|
||||||
|
R_RSA_PUBLIC_KEY *, R_RANDOM_STRUCT *));
|
||||||
|
int RSAPrivateEncrypt PROTO_LIST
|
||||||
|
((unsigned char *, unsigned int *, unsigned char *, unsigned int,
|
||||||
|
R_RSA_PRIVATE_KEY *));
|
||||||
|
int RSAPublicDecrypt PROTO_LIST
|
||||||
|
((unsigned char *, unsigned int *, unsigned char *, unsigned int,
|
||||||
|
R_RSA_PUBLIC_KEY *));
|
||||||
|
int RSAPrivateDecrypt PROTO_LIST
|
||||||
|
((unsigned char *, unsigned int *, unsigned char *, unsigned int,
|
||||||
|
R_RSA_PRIVATE_KEY *));
|
253
lib/rsaref/rsaref.h
Normal file
253
lib/rsaref/rsaref.h
Normal file
|
@ -0,0 +1,253 @@
|
||||||
|
/* RSAREF.H - header file for RSAREF cryptographic toolkit
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Copyright (C) RSA Laboratories, a division of RSA Data Security,
|
||||||
|
Inc., created 1991. All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _RSAREF_H_
|
||||||
|
#define _RSAREF_H_ 1
|
||||||
|
|
||||||
|
#include "global.h"
|
||||||
|
#include "md2.h"
|
||||||
|
#include "md5.h"
|
||||||
|
#include "des.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Message-digest algorithms.
|
||||||
|
*/
|
||||||
|
#define DA_MD2 3
|
||||||
|
#define DA_MD5 5
|
||||||
|
|
||||||
|
/* Encryption algorithms to be ored with digest algorithm in Seal and Open.
|
||||||
|
*/
|
||||||
|
#define EA_DES_CBC 1
|
||||||
|
#define EA_DES_EDE2_CBC 2
|
||||||
|
#define EA_DES_EDE3_CBC 3
|
||||||
|
#define EA_DESX_CBC 4
|
||||||
|
|
||||||
|
/* RSA key lengths.
|
||||||
|
*/
|
||||||
|
#define MIN_RSA_MODULUS_BITS 508
|
||||||
|
#define MAX_RSA_MODULUS_BITS 1024
|
||||||
|
#define MAX_RSA_MODULUS_LEN ((MAX_RSA_MODULUS_BITS + 7) / 8)
|
||||||
|
#define MAX_RSA_PRIME_BITS ((MAX_RSA_MODULUS_BITS + 1) / 2)
|
||||||
|
#define MAX_RSA_PRIME_LEN ((MAX_RSA_PRIME_BITS + 7) / 8)
|
||||||
|
|
||||||
|
/* Maximum lengths of encoded and encrypted content, as a function of
|
||||||
|
content length len. Also, inverse functions.
|
||||||
|
*/
|
||||||
|
#define ENCODED_CONTENT_LEN(len) (4*(len)/3 + 3)
|
||||||
|
#define ENCRYPTED_CONTENT_LEN(len) ENCODED_CONTENT_LEN ((len)+8)
|
||||||
|
#define DECODED_CONTENT_LEN(len) (3*(len)/4 + 1)
|
||||||
|
#define DECRYPTED_CONTENT_LEN(len) (DECODED_CONTENT_LEN (len) - 1)
|
||||||
|
|
||||||
|
/* Maximum lengths of signatures, encrypted keys, encrypted
|
||||||
|
signatures, and message digests.
|
||||||
|
*/
|
||||||
|
#define MAX_SIGNATURE_LEN MAX_RSA_MODULUS_LEN
|
||||||
|
#define MAX_PEM_SIGNATURE_LEN ENCODED_CONTENT_LEN (MAX_SIGNATURE_LEN)
|
||||||
|
#define MAX_ENCRYPTED_KEY_LEN MAX_RSA_MODULUS_LEN
|
||||||
|
#define MAX_PEM_ENCRYPTED_KEY_LEN ENCODED_CONTENT_LEN (MAX_ENCRYPTED_KEY_LEN)
|
||||||
|
#define MAX_PEM_ENCRYPTED_SIGNATURE_LEN \
|
||||||
|
ENCRYPTED_CONTENT_LEN (MAX_SIGNATURE_LEN)
|
||||||
|
#define MAX_DIGEST_LEN 16
|
||||||
|
|
||||||
|
/* Maximum length of Diffie-Hellman parameters.
|
||||||
|
*/
|
||||||
|
#define DH_PRIME_LEN(bits) (((bits) + 7) / 8)
|
||||||
|
|
||||||
|
/* Error codes.
|
||||||
|
*/
|
||||||
|
#define RE_CONTENT_ENCODING 0x0400
|
||||||
|
#define RE_DATA 0x0401
|
||||||
|
#define RE_DIGEST_ALGORITHM 0x0402
|
||||||
|
#define RE_ENCODING 0x0403
|
||||||
|
#define RE_KEY 0x0404
|
||||||
|
#define RE_KEY_ENCODING 0x0405
|
||||||
|
#define RE_LEN 0x0406
|
||||||
|
#define RE_MODULUS_LEN 0x0407
|
||||||
|
#define RE_NEED_RANDOM 0x0408
|
||||||
|
#define RE_PRIVATE_KEY 0x0409
|
||||||
|
#define RE_PUBLIC_KEY 0x040a
|
||||||
|
#define RE_SIGNATURE 0x040b
|
||||||
|
#define RE_SIGNATURE_ENCODING 0x040c
|
||||||
|
#define RE_ENCRYPTION_ALGORITHM 0x040d
|
||||||
|
|
||||||
|
/* Random structure.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
unsigned int bytesNeeded;
|
||||||
|
unsigned char state[16];
|
||||||
|
unsigned int outputAvailable;
|
||||||
|
unsigned char output[16];
|
||||||
|
} R_RANDOM_STRUCT;
|
||||||
|
|
||||||
|
/* RSA public and private key.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
unsigned int bits; /* length in bits of modulus */
|
||||||
|
unsigned char modulus[MAX_RSA_MODULUS_LEN]; /* modulus */
|
||||||
|
unsigned char exponent[MAX_RSA_MODULUS_LEN]; /* public exponent */
|
||||||
|
} R_RSA_PUBLIC_KEY;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned int bits; /* length in bits of modulus */
|
||||||
|
unsigned char modulus[MAX_RSA_MODULUS_LEN]; /* modulus */
|
||||||
|
unsigned char publicExponent[MAX_RSA_MODULUS_LEN]; /* public exponent */
|
||||||
|
unsigned char exponent[MAX_RSA_MODULUS_LEN]; /* private exponent */
|
||||||
|
unsigned char prime[2][MAX_RSA_PRIME_LEN]; /* prime factors */
|
||||||
|
unsigned char primeExponent[2][MAX_RSA_PRIME_LEN]; /* exponents for CRT */
|
||||||
|
unsigned char coefficient[MAX_RSA_PRIME_LEN]; /* CRT coefficient */
|
||||||
|
} R_RSA_PRIVATE_KEY;
|
||||||
|
|
||||||
|
/* RSA prototype key.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
unsigned int bits; /* length in bits of modulus */
|
||||||
|
int useFermat4; /* public exponent (1 = F4, 0 = 3) */
|
||||||
|
} R_RSA_PROTO_KEY;
|
||||||
|
|
||||||
|
/* Diffie-Hellman parameters.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
unsigned char *prime; /* prime */
|
||||||
|
unsigned int primeLen; /* length of prime */
|
||||||
|
unsigned char *generator; /* generator */
|
||||||
|
unsigned int generatorLen; /* length of generator */
|
||||||
|
} R_DH_PARAMS;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int digestAlgorithm;
|
||||||
|
union {
|
||||||
|
MD2_CTX md2;
|
||||||
|
MD5_CTX md5;
|
||||||
|
} context;
|
||||||
|
} R_DIGEST_CTX;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
R_DIGEST_CTX digestContext;
|
||||||
|
} R_SIGNATURE_CTX;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int encryptionAlgorithm;
|
||||||
|
union {
|
||||||
|
DES_CBC_CTX des;
|
||||||
|
DES3_CBC_CTX des3;
|
||||||
|
DESX_CBC_CTX desx;
|
||||||
|
} cipherContext;
|
||||||
|
|
||||||
|
unsigned char buffer[8];
|
||||||
|
unsigned int bufferLen;
|
||||||
|
} R_ENVELOPE_CTX;
|
||||||
|
|
||||||
|
/* Random structures.
|
||||||
|
*/
|
||||||
|
int R_RandomInit PROTO_LIST ((R_RANDOM_STRUCT *));
|
||||||
|
int R_RandomUpdate PROTO_LIST
|
||||||
|
((R_RANDOM_STRUCT *, unsigned char *, unsigned int));
|
||||||
|
int R_GetRandomBytesNeeded PROTO_LIST ((unsigned int *, R_RANDOM_STRUCT *));
|
||||||
|
void R_RandomFinal PROTO_LIST ((R_RANDOM_STRUCT *));
|
||||||
|
|
||||||
|
/* Cryptographic procedures "by parts"
|
||||||
|
*/
|
||||||
|
int R_DigestInit PROTO_LIST ((R_DIGEST_CTX *, int));
|
||||||
|
int R_DigestUpdate PROTO_LIST
|
||||||
|
((R_DIGEST_CTX *, unsigned char *, unsigned int));
|
||||||
|
int R_DigestFinal PROTO_LIST
|
||||||
|
((R_DIGEST_CTX *, unsigned char *, unsigned int *));
|
||||||
|
|
||||||
|
int R_SignInit PROTO_LIST ((R_SIGNATURE_CTX *, int));
|
||||||
|
int R_SignUpdate PROTO_LIST
|
||||||
|
((R_SIGNATURE_CTX *, unsigned char *, unsigned int));
|
||||||
|
int R_SignFinal PROTO_LIST
|
||||||
|
((R_SIGNATURE_CTX *, unsigned char *, unsigned int *, R_RSA_PRIVATE_KEY *));
|
||||||
|
|
||||||
|
int R_VerifyInit PROTO_LIST ((R_SIGNATURE_CTX *, int));
|
||||||
|
int R_VerifyUpdate PROTO_LIST
|
||||||
|
((R_SIGNATURE_CTX *, unsigned char *, unsigned int));
|
||||||
|
int R_VerifyFinal PROTO_LIST
|
||||||
|
((R_SIGNATURE_CTX *, unsigned char *, unsigned int, R_RSA_PUBLIC_KEY *));
|
||||||
|
|
||||||
|
int R_SealInit PROTO_LIST
|
||||||
|
((R_ENVELOPE_CTX *, unsigned char **, unsigned int *, unsigned char [8],
|
||||||
|
unsigned int, R_RSA_PUBLIC_KEY **, int, R_RANDOM_STRUCT *));
|
||||||
|
int R_SealUpdate PROTO_LIST
|
||||||
|
((R_ENVELOPE_CTX *, unsigned char *, unsigned int *, unsigned char *,
|
||||||
|
unsigned int));
|
||||||
|
int R_SealFinal PROTO_LIST
|
||||||
|
((R_ENVELOPE_CTX *, unsigned char *, unsigned int *));
|
||||||
|
|
||||||
|
int R_OpenInit PROTO_LIST
|
||||||
|
((R_ENVELOPE_CTX *, int, unsigned char *, unsigned int, unsigned char [8],
|
||||||
|
R_RSA_PRIVATE_KEY *));
|
||||||
|
int R_OpenUpdate PROTO_LIST
|
||||||
|
((R_ENVELOPE_CTX *, unsigned char *, unsigned int *, unsigned char *,
|
||||||
|
unsigned int));
|
||||||
|
int R_OpenFinal PROTO_LIST
|
||||||
|
((R_ENVELOPE_CTX *, unsigned char *, unsigned int *));
|
||||||
|
|
||||||
|
/* Cryptographic enhancements by block.
|
||||||
|
*/
|
||||||
|
int R_SignPEMBlock PROTO_LIST
|
||||||
|
((unsigned char *, unsigned int *, unsigned char *, unsigned int *,
|
||||||
|
unsigned char *, unsigned int, int, int, R_RSA_PRIVATE_KEY *));
|
||||||
|
int R_SignBlock PROTO_LIST
|
||||||
|
((unsigned char *, unsigned int *, unsigned char *, unsigned int, int,
|
||||||
|
R_RSA_PRIVATE_KEY *));
|
||||||
|
int R_VerifyPEMSignature PROTO_LIST
|
||||||
|
((unsigned char *, unsigned int *, unsigned char *, unsigned int,
|
||||||
|
unsigned char *, unsigned int, int, int, R_RSA_PUBLIC_KEY *));
|
||||||
|
int R_VerifyBlockSignature PROTO_LIST
|
||||||
|
((unsigned char *, unsigned int, unsigned char *, unsigned int, int,
|
||||||
|
R_RSA_PUBLIC_KEY *));
|
||||||
|
int R_SealPEMBlock PROTO_LIST
|
||||||
|
((unsigned char *, unsigned int *, unsigned char *, unsigned int *,
|
||||||
|
unsigned char *, unsigned int *, unsigned char [8], unsigned char *,
|
||||||
|
unsigned int, int, R_RSA_PUBLIC_KEY *, R_RSA_PRIVATE_KEY *,
|
||||||
|
R_RANDOM_STRUCT *));
|
||||||
|
int R_OpenPEMBlock PROTO_LIST
|
||||||
|
((unsigned char *, unsigned int *, unsigned char *, unsigned int,
|
||||||
|
unsigned char *, unsigned int, unsigned char *, unsigned int,
|
||||||
|
unsigned char [8], int, R_RSA_PRIVATE_KEY *, R_RSA_PUBLIC_KEY *));
|
||||||
|
int R_DigestBlock PROTO_LIST
|
||||||
|
((unsigned char *, unsigned int *, unsigned char *, unsigned int, int));
|
||||||
|
|
||||||
|
/* Printable ASCII encoding and decoding.
|
||||||
|
*/
|
||||||
|
int R_EncodePEMBlock PROTO_LIST
|
||||||
|
((unsigned char *, unsigned int *, unsigned char *, unsigned int));
|
||||||
|
int R_DecodePEMBlock PROTO_LIST
|
||||||
|
((unsigned char *, unsigned int *, unsigned char *, unsigned int));
|
||||||
|
|
||||||
|
/* Key-pair generation.
|
||||||
|
*/
|
||||||
|
int R_GeneratePEMKeys PROTO_LIST
|
||||||
|
((R_RSA_PUBLIC_KEY *, R_RSA_PRIVATE_KEY *, R_RSA_PROTO_KEY *,
|
||||||
|
R_RANDOM_STRUCT *));
|
||||||
|
|
||||||
|
/* Diffie-Hellman key agreement.
|
||||||
|
*/
|
||||||
|
int R_GenerateDHParams PROTO_LIST
|
||||||
|
((R_DH_PARAMS *, unsigned int, unsigned int, R_RANDOM_STRUCT *));
|
||||||
|
int R_SetupDHAgreement PROTO_LIST
|
||||||
|
((unsigned char *, unsigned char *, unsigned int, R_DH_PARAMS *,
|
||||||
|
R_RANDOM_STRUCT *));
|
||||||
|
int R_ComputeDHAgreedKey PROTO_LIST
|
||||||
|
((unsigned char *, unsigned char *, unsigned char *, unsigned int,
|
||||||
|
R_DH_PARAMS *));
|
||||||
|
|
||||||
|
/* Routines supplied by the implementor.
|
||||||
|
*/
|
||||||
|
void R_memset PROTO_LIST ((POINTER, int, unsigned int));
|
||||||
|
void R_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int));
|
||||||
|
int R_memcmp PROTO_LIST ((POINTER, POINTER, unsigned int));
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
79
t/Makefile.am
Normal file
79
t/Makefile.am
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
# $Id$
|
||||||
|
|
||||||
|
AM_CPPFLAGS = -I$(top_srcdir)/include
|
||||||
|
|
||||||
|
if WITH_BENCHMARKS
|
||||||
|
AM_CPPFLAGS += -DBENCHMARKS
|
||||||
|
endif
|
||||||
|
|
||||||
|
noinst_HEADERS = t.h
|
||||||
|
|
||||||
|
# Common support code
|
||||||
|
check_LTLIBRARIES = libt.la
|
||||||
|
libt_la_SOURCES = t_main.c t_file.c
|
||||||
|
|
||||||
|
# Link in the test driver and the full cryb library
|
||||||
|
LDADD = $(builddir)/libt.la \
|
||||||
|
$(top_builddir)/lib/core/libcryb-core.la \
|
||||||
|
$(top_builddir)/lib/enc/libcryb-enc.la \
|
||||||
|
$(top_builddir)/lib/digest/libcryb-digest.la \
|
||||||
|
$(top_builddir)/lib/mac/libcryb-mac.la \
|
||||||
|
$(top_builddir)/lib/rand/libcryb-rand.la \
|
||||||
|
$(top_builddir)/lib/oath/libcryb-oath.la
|
||||||
|
|
||||||
|
# Additional headers, flags and libraries for OpenSSL
|
||||||
|
if WITH_OPENSSL
|
||||||
|
OPENSSL_INCLUDES = $(INCLUDES)
|
||||||
|
OPENSSL_CFLAGS = -DWITH_OPENSSL=1
|
||||||
|
OPENSSL_LDADD = $(LDADD) -lcrypto
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Additional headers, flags and libraries for RSAREF
|
||||||
|
if WITH_RSAREF
|
||||||
|
RSAREF_INCLUDES = $(INCLUDES) -I$(top_srcdir)/lib/rsaref
|
||||||
|
RSAREF_CFLAGS = -DWITH_RSAREF=1 -DPROTOTYPES=1
|
||||||
|
RSAREF_LDADD = $(LDADD) $(top_builddir)/lib/rsaref/librsaref.la
|
||||||
|
endif
|
||||||
|
|
||||||
|
# tests
|
||||||
|
TESTS =
|
||||||
|
|
||||||
|
# libcryb-core
|
||||||
|
TESTS += t_ctype
|
||||||
|
|
||||||
|
# libcryb-enc
|
||||||
|
TESTS += t_rfc3986 t_rfc4648
|
||||||
|
|
||||||
|
# libcryb-digest
|
||||||
|
TESTS += t_md5
|
||||||
|
if WITH_OPENSSL
|
||||||
|
TESTS += t_md5_openssl
|
||||||
|
t_md5_openssl_SOURCES = t_md5.c
|
||||||
|
t_md5_openssl_CFLAGS = $(OPENSSL_INCLUDES) $(OPENSSL_CFLAGS)
|
||||||
|
t_md5_openssl_LDADD = $(OPENSSL_LDADD)
|
||||||
|
endif
|
||||||
|
if WITH_RSAREF
|
||||||
|
TESTS += t_md5_rsaref
|
||||||
|
t_md5_rsaref_SOURCES = t_md5.c
|
||||||
|
t_md5_rsaref_CFLAGS = $(RSAREF_INCLUDES) $(RSAREF_CFLAGS)
|
||||||
|
t_md5_rsaref_LDADD = $(RSAREF_LDADD)
|
||||||
|
endif
|
||||||
|
|
||||||
|
TESTS += t_sha1
|
||||||
|
if WITH_OPENSSL
|
||||||
|
TESTS += t_sha1_openssl
|
||||||
|
t_sha1_openssl_SOURCES = t_sha1.c
|
||||||
|
t_sha1_openssl_CFLAGS = $(OPENSSL_INCLUDES) $(OPENSSL_CFLAGS)
|
||||||
|
t_sha1_openssl_LDADD = $(OPENSSL_LDADD)
|
||||||
|
endif
|
||||||
|
|
||||||
|
# libcryb-mac
|
||||||
|
TESTS += t_hmac
|
||||||
|
if WITH_OPENSSL
|
||||||
|
TESTS += t_hmac_openssl
|
||||||
|
t_hmac_openssl_SOURCES = t_hmac.c
|
||||||
|
t_hmac_openssl_CFLAGS = $(OPENSSL_INCLUDES) $(OPENSSL_CFLAGS)
|
||||||
|
t_hmac_openssl_LDADD = $(OPENSSL_LDADD)
|
||||||
|
endif
|
||||||
|
|
||||||
|
check_PROGRAMS = $(TESTS)
|
82
t/t.h
Normal file
82
t/t.h
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2012-2014 Dag-Erling Smørgrav
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote
|
||||||
|
* products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Dag-Erling Smørgrav <des@des.no>
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef T_H_INCLUDED
|
||||||
|
#define T_H_INCLUDED
|
||||||
|
|
||||||
|
CRYB_DISABLE_COVERAGE
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Structure describing a test. Includes a pointer to the function that
|
||||||
|
* performs the test, a pointer to the default description or comment
|
||||||
|
* associated with the test, and a pointer to arbitrary data passed to the
|
||||||
|
* test function.
|
||||||
|
*/
|
||||||
|
typedef int (t_func)(char **, void *);
|
||||||
|
struct t_test {
|
||||||
|
t_func *func;
|
||||||
|
void *arg;
|
||||||
|
char *desc;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern const char *t_progname;
|
||||||
|
|
||||||
|
void t_add_test(t_func *, void *, const char *, ...);
|
||||||
|
void t_add_tests(struct t_test *, int);
|
||||||
|
|
||||||
|
int t_prepare(int, char **);
|
||||||
|
void t_cleanup(void);
|
||||||
|
|
||||||
|
void t_verbose_hex(const uint8_t *, size_t);
|
||||||
|
void t_verbose(const char *, ...)
|
||||||
|
CRYB_PRINTF(1, 2);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convenience functions for temp files
|
||||||
|
*/
|
||||||
|
struct t_file {
|
||||||
|
char *name;
|
||||||
|
FILE *file;
|
||||||
|
struct t_file *prev, *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct t_file *t_fopen(const char *);
|
||||||
|
int t_fprintf(struct t_file *, const char *, ...)
|
||||||
|
CRYB_PRINTF(2, 3);
|
||||||
|
int t_ferror(struct t_file *);
|
||||||
|
int t_feof(struct t_file *);
|
||||||
|
void t_frewind(struct t_file *);
|
||||||
|
void t_fclose(struct t_file *);
|
||||||
|
void t_fcloseall(void);
|
||||||
|
|
||||||
|
#endif
|
123
t/t_ctype.c
Normal file
123
t/t_ctype.c
Normal file
|
@ -0,0 +1,123 @@
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2014 Dag-Erling Smørgrav
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote
|
||||||
|
* products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Dag-Erling Smørgrav <des@des.no>
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "cryb/impl.h"
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <cryb/ctype.h>
|
||||||
|
|
||||||
|
#include "t.h"
|
||||||
|
|
||||||
|
#define OC_DIGIT "0123456789"
|
||||||
|
#define OC_XDIGIT OC_DIGIT "ABCDEFabcdef"
|
||||||
|
#define OC_UPPER "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||||
|
#define OC_LOWER "abcdefghijklmnopqrstuvwxyz"
|
||||||
|
#define OC_LETTER OC_UPPER OC_LOWER
|
||||||
|
#define OC_LWS " \t\f\r"
|
||||||
|
#define OC_WS OC_LWS "\n"
|
||||||
|
#define OC_P "!\"#$%&'()*+,-./" OC_DIGIT ":;<=>?@" OC_UPPER "[\\]^_`" OC_LOWER "{|}~"
|
||||||
|
#define OC_PFCS OC_DIGIT OC_LETTER "._-"
|
||||||
|
|
||||||
|
static const char oc_digit[] = OC_DIGIT;
|
||||||
|
static const char oc_xdigit[] = OC_XDIGIT;
|
||||||
|
static const char oc_upper[] = OC_UPPER;
|
||||||
|
static const char oc_lower[] = OC_LOWER;
|
||||||
|
static const char oc_letter[] = OC_LETTER;
|
||||||
|
static const char oc_lws[] = OC_LWS;
|
||||||
|
static const char oc_ws[] = OC_WS;
|
||||||
|
static const char oc_p[] = OC_P;
|
||||||
|
static const char oc_pfcs[] = OC_PFCS;
|
||||||
|
|
||||||
|
#define T_OC(set) \
|
||||||
|
static int \
|
||||||
|
t_oc_##set(char **desc, void *arg) \
|
||||||
|
{ \
|
||||||
|
char crib[256]; \
|
||||||
|
unsigned int i, ret; \
|
||||||
|
\
|
||||||
|
(void)desc; \
|
||||||
|
(void)arg; \
|
||||||
|
memset(crib, 0, sizeof crib); \
|
||||||
|
for (i = 0; oc_##set[i]; ++i) \
|
||||||
|
crib[(int)oc_##set[i]] = 1; \
|
||||||
|
for (i = ret = 0; i < sizeof crib; ++i) { \
|
||||||
|
if (is_##set(i) != crib[i]) { \
|
||||||
|
t_verbose("is_%s() incorrect " \
|
||||||
|
"for %#02x\n", #set, i); \
|
||||||
|
++ret; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
return (ret == 0); \
|
||||||
|
}
|
||||||
|
#define T_OC_ADD(set) t_add_test(&t_oc_##set, NULL, "is_"#set)
|
||||||
|
|
||||||
|
T_OC(digit)
|
||||||
|
T_OC(xdigit)
|
||||||
|
T_OC(upper)
|
||||||
|
T_OC(lower)
|
||||||
|
T_OC(letter)
|
||||||
|
T_OC(lws)
|
||||||
|
T_OC(ws)
|
||||||
|
T_OC(p)
|
||||||
|
T_OC(pfcs)
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
* Boilerplate
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
t_prepare(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
|
||||||
|
(void)argc;
|
||||||
|
(void)argv;
|
||||||
|
T_OC_ADD(digit);
|
||||||
|
T_OC_ADD(xdigit);
|
||||||
|
T_OC_ADD(upper);
|
||||||
|
T_OC_ADD(lower);
|
||||||
|
T_OC_ADD(letter);
|
||||||
|
T_OC_ADD(lws);
|
||||||
|
T_OC_ADD(ws);
|
||||||
|
T_OC_ADD(p);
|
||||||
|
T_OC_ADD(pfcs);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
t_cleanup(void)
|
||||||
|
{
|
||||||
|
}
|
158
t/t_file.c
Normal file
158
t/t_file.c
Normal file
|
@ -0,0 +1,158 @@
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2012-2014 Dag-Erling Smørgrav
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote
|
||||||
|
* products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Dag-Erling Smørgrav <des@des.no>
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "cryb/impl.h"
|
||||||
|
|
||||||
|
#include <err.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "t.h"
|
||||||
|
|
||||||
|
static struct t_file *tflist;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Open a temp file.
|
||||||
|
*/
|
||||||
|
struct t_file *
|
||||||
|
t_fopen(const char *filename)
|
||||||
|
{
|
||||||
|
struct t_file *tf;
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
if ((tf = calloc(sizeof *tf, 1)) == NULL)
|
||||||
|
err(1, "%s(): calloc()", __func__);
|
||||||
|
if (filename) {
|
||||||
|
if ((tf->name = strdup(filename)) == NULL)
|
||||||
|
err(1, "%s(): strdup()", __func__);
|
||||||
|
} else {
|
||||||
|
asprintf(&tf->name, "%s.%lu.%p.tmp",
|
||||||
|
t_progname, (unsigned long)getpid(), (void *)tf);
|
||||||
|
if (tf->name == NULL)
|
||||||
|
err(1, "%s(): asprintf()", __func__);
|
||||||
|
}
|
||||||
|
if ((fd = open(tf->name, O_RDWR|O_CREAT|O_TRUNC, 0600)) < 0)
|
||||||
|
err(1, "%s(): %s", __func__, tf->name);
|
||||||
|
if ((tf->file = fdopen(fd, "r+")) == NULL)
|
||||||
|
err(1, "%s(): fdopen()", __func__);
|
||||||
|
if ((tf->next = tflist) != NULL)
|
||||||
|
tf->next->prev = tf;
|
||||||
|
tflist = tf;
|
||||||
|
return (tf);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Write text to the temp file.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
t_fprintf(struct t_file *tf, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
va_start(ap, fmt);
|
||||||
|
len = vfprintf(tf->file, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
if (ferror(tf->file))
|
||||||
|
err(1, "%s(): vfprintf()", __func__);
|
||||||
|
return (len);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Rewind the temp file.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
t_frewind(struct t_file *tf)
|
||||||
|
{
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
rewind(tf->file);
|
||||||
|
if (errno != 0)
|
||||||
|
err(1, "%s(): rewind()", __func__);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return non-zero if an error occurred.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
t_ferror(struct t_file *tf)
|
||||||
|
{
|
||||||
|
|
||||||
|
return (ferror(tf->file));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return non-zero if the end of the file was reached.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
t_feof(struct t_file *tf)
|
||||||
|
{
|
||||||
|
|
||||||
|
return (feof(tf->file));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Close a temp file.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
t_fclose(struct t_file *tf)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (tf == tflist)
|
||||||
|
tflist = tf->next;
|
||||||
|
if (tf->prev)
|
||||||
|
tf->prev->next = tf->next;
|
||||||
|
if (tf->next)
|
||||||
|
tf->next->prev = tf->prev;
|
||||||
|
fclose(tf->file);
|
||||||
|
if (unlink(tf->name) < 0)
|
||||||
|
warn("%s(): unlink()", __func__);
|
||||||
|
free(tf->name);
|
||||||
|
free(tf);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* atexit() function to close all remaining files.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
t_fcloseall(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
while (tflist)
|
||||||
|
t_fclose(tflist);
|
||||||
|
}
|
225
t/t_hmac.c
Normal file
225
t/t_hmac.c
Normal file
|
@ -0,0 +1,225 @@
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2012 Universitetet i Oslo
|
||||||
|
* Copyright (c) 2012 Dag-Erling Smørgrav
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote
|
||||||
|
* products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Dag-Erling Smørgrav <des@des.no>
|
||||||
|
* Sponsor: the University of Oslo
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "cryb/impl.h"
|
||||||
|
|
||||||
|
#include <err.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "t.h"
|
||||||
|
|
||||||
|
#if WITH_OPENSSL
|
||||||
|
|
||||||
|
#include <openssl/evp.h>
|
||||||
|
#include <openssl/hmac.h>
|
||||||
|
|
||||||
|
#define HMAC_LEN 20
|
||||||
|
|
||||||
|
static void
|
||||||
|
t_hmac_complete(const void *key, size_t keylen,
|
||||||
|
const void *msg, size_t msglen, uint8_t *mac)
|
||||||
|
{
|
||||||
|
HMAC_CTX ctx;
|
||||||
|
|
||||||
|
HMAC_CTX_init(&ctx);
|
||||||
|
HMAC_Init_ex(&ctx, key, keylen, EVP_sha1(), NULL);
|
||||||
|
HMAC_Update(&ctx, msg, msglen);
|
||||||
|
HMAC_Final(&ctx, mac, NULL);
|
||||||
|
HMAC_CTX_cleanup(&ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#include <cryb/sha1.h>
|
||||||
|
#include <cryb/hmac.h>
|
||||||
|
|
||||||
|
#define t_hmac_complete(key, keylen, msg, msglen, mac) \
|
||||||
|
hmac_complete(key, keylen, msg, msglen, mac)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Test vectors from FIPS 198
|
||||||
|
*/
|
||||||
|
static struct t_vector {
|
||||||
|
const char *desc;
|
||||||
|
uint8_t key[100];
|
||||||
|
size_t keylen;
|
||||||
|
const char *msg;
|
||||||
|
const uint8_t mac[HMAC_LEN];
|
||||||
|
} t_hmac_vectors[] = {
|
||||||
|
{
|
||||||
|
"zero-length key, zero-length message",
|
||||||
|
{ },
|
||||||
|
0,
|
||||||
|
"",
|
||||||
|
{
|
||||||
|
0xfb, 0xdb, 0x1d, 0x1b, 0x18, 0xaa, 0x6c, 0x08,
|
||||||
|
0x32, 0x4b, 0x7d, 0x64, 0xb7, 0x1f, 0xb7, 0x63,
|
||||||
|
0x70, 0x69, 0x0e, 0x1d,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"FIPS 198 A.1 (64-byte key)",
|
||||||
|
{
|
||||||
|
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||||
|
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
||||||
|
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
|
||||||
|
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
|
||||||
|
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
|
||||||
|
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
|
||||||
|
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
|
||||||
|
0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
|
||||||
|
},
|
||||||
|
64,
|
||||||
|
"Sample #1",
|
||||||
|
{
|
||||||
|
0x4f, 0x4c, 0xa3, 0xd5, 0xd6, 0x8b, 0xa7, 0xcc,
|
||||||
|
0x0a, 0x12, 0x08, 0xc9, 0xc6, 0x1e, 0x9c, 0x5d,
|
||||||
|
0xa0, 0x40, 0x3c, 0x0a,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"FIPS 198 A.2 (20-byte key)",
|
||||||
|
{
|
||||||
|
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
|
||||||
|
0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
|
||||||
|
0x40, 0x41, 0x42, 0x43,
|
||||||
|
},
|
||||||
|
20,
|
||||||
|
"Sample #2",
|
||||||
|
{
|
||||||
|
0x09, 0x22, 0xd3, 0x40, 0x5f, 0xaa, 0x3d, 0x19,
|
||||||
|
0x4f, 0x82, 0xa4, 0x58, 0x30, 0x73, 0x7d, 0x5c,
|
||||||
|
0xc6, 0xc7, 0x5d, 0x24,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"FIPS 198 A.3 (100-byte key)",
|
||||||
|
{
|
||||||
|
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
|
||||||
|
0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
|
||||||
|
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
|
||||||
|
0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
|
||||||
|
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
|
||||||
|
0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
|
||||||
|
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
|
||||||
|
0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
|
||||||
|
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
|
||||||
|
0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
|
||||||
|
0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
|
||||||
|
0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
|
||||||
|
0xb0, 0xb1, 0xb2, 0xb3,
|
||||||
|
},
|
||||||
|
100,
|
||||||
|
"Sample #3",
|
||||||
|
{
|
||||||
|
0xbc, 0xf4, 0x1e, 0xab, 0x8b, 0xb2, 0xd8, 0x02,
|
||||||
|
0xf3, 0xd0, 0x5c, 0xaf, 0x7c, 0xb0, 0x92, 0xec,
|
||||||
|
0xf8, 0xd1, 0xa3, 0xaa,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"FIPS 198 A.4 (49-byte key)",
|
||||||
|
{
|
||||||
|
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
|
||||||
|
0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
|
||||||
|
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
|
||||||
|
0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
|
||||||
|
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
|
||||||
|
0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
|
||||||
|
0xa0,
|
||||||
|
},
|
||||||
|
49,
|
||||||
|
"Sample #4",
|
||||||
|
{
|
||||||
|
0x9e, 0xa8, 0x86, 0xef, 0xe2, 0x68, 0xdb, 0xec,
|
||||||
|
0xce, 0x42, 0x0c, 0x75, 0x24, 0xdf, 0x32, 0xe0,
|
||||||
|
0x75, 0x1a, 0x2a, 0x26,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Unit test: compute the HMAC signature of the specified string with the
|
||||||
|
* specified key and compare it to the expected result.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
t_hmac_vector(char **desc CRYB_UNUSED, void *arg)
|
||||||
|
{
|
||||||
|
struct t_vector *vector = (struct t_vector *)arg;
|
||||||
|
uint8_t mac[HMAC_LEN];
|
||||||
|
|
||||||
|
t_hmac_complete(vector->key, vector->keylen,
|
||||||
|
(const uint8_t *)vector->msg, strlen(vector->msg),
|
||||||
|
mac);
|
||||||
|
if (memcmp(mac, vector->mac, HMAC_LEN) != 0) {
|
||||||
|
t_verbose("expected ");
|
||||||
|
t_verbose_hex(vector->mac, HMAC_LEN);
|
||||||
|
t_verbose("\n");
|
||||||
|
t_verbose("got ");
|
||||||
|
t_verbose_hex(mac, HMAC_LEN);
|
||||||
|
t_verbose("\n");
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
* Boilerplate
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
t_prepare(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int i, n;
|
||||||
|
|
||||||
|
(void)argc;
|
||||||
|
(void)argv;
|
||||||
|
n = sizeof t_hmac_vectors / sizeof t_hmac_vectors[0];
|
||||||
|
for (i = 0; i < n; ++i)
|
||||||
|
t_add_test(t_hmac_vector, &t_hmac_vectors[i],
|
||||||
|
t_hmac_vectors[i].desc);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
t_cleanup(void)
|
||||||
|
{
|
||||||
|
}
|
204
t/t_main.c
Normal file
204
t/t_main.c
Normal file
|
@ -0,0 +1,204 @@
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2012-2014 Dag-Erling Smørgrav
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote
|
||||||
|
* products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Dag-Erling Smørgrav <des@des.no>
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "cryb/impl.h"
|
||||||
|
|
||||||
|
#include <err.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <syslog.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "t.h"
|
||||||
|
|
||||||
|
/* program name */
|
||||||
|
const char *t_progname;
|
||||||
|
|
||||||
|
/* verbose flag */
|
||||||
|
static int verbose;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If verbose flag is set, print an array of bytes in hex
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
t_verbose_hex(const uint8_t *buf, size_t len)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (verbose)
|
||||||
|
while (len--)
|
||||||
|
fprintf(stderr, "%02x", *buf++);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If verbose flag is set, print a message
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
t_verbose(const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
if (verbose) {
|
||||||
|
va_start(ap, fmt);
|
||||||
|
vfprintf(stderr, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Test plan
|
||||||
|
*/
|
||||||
|
static struct t_test **t_plan;
|
||||||
|
static size_t t_plan_len, t_plan_size;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Grow the test plan to accomodate at least n more entries.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
t_grow(int n)
|
||||||
|
{
|
||||||
|
struct t_test **p;
|
||||||
|
|
||||||
|
if (t_plan_len + n < t_plan_size)
|
||||||
|
return;
|
||||||
|
if (t_plan_size == 0)
|
||||||
|
t_plan_size = 16;
|
||||||
|
while (t_plan_len + n >= t_plan_size)
|
||||||
|
t_plan_size *= 2;
|
||||||
|
if ((p = realloc(t_plan, t_plan_size * sizeof *p)) == NULL)
|
||||||
|
err(1, "realloc()");
|
||||||
|
t_plan = p;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add a single entry to the test plan.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
t_add_test(t_func *func, void *arg, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
struct t_test *t;
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
if ((t = malloc(sizeof *t)) == NULL)
|
||||||
|
err(1, "malloc()");
|
||||||
|
t->func = func;
|
||||||
|
va_start(ap, fmt);
|
||||||
|
vasprintf(&t->desc, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
t->arg = arg;
|
||||||
|
t_grow(1);
|
||||||
|
t_plan[t_plan_len++] = t;
|
||||||
|
t_plan[t_plan_len] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add multiple entries to the test plan.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
t_add_tests(struct t_test *t, int n)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
t_grow(n);
|
||||||
|
for (i = 0; i < n; ++i)
|
||||||
|
t_plan[t_plan_len++] = &t[i];
|
||||||
|
t_plan[t_plan_len] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Print usage string and exit.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
usage(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
fprintf(stderr, "usage: %s [-v]\n", t_progname);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
unsigned int n, pass, fail;
|
||||||
|
char *desc;
|
||||||
|
int opt;
|
||||||
|
|
||||||
|
/* make stdout line-buffered to preserve ordering */
|
||||||
|
setvbuf(stdout, NULL, _IOLBF, 0);
|
||||||
|
|
||||||
|
/* clean up temp files in case of premature exit */
|
||||||
|
atexit(t_fcloseall);
|
||||||
|
|
||||||
|
/* determine our own name, for naming temp files etc. */
|
||||||
|
if ((t_progname = strrchr(argv[0], '/')) != NULL)
|
||||||
|
t_progname++; /* one past the slash */
|
||||||
|
else
|
||||||
|
t_progname = argv[0];
|
||||||
|
|
||||||
|
/* parse command line options */
|
||||||
|
while ((opt = getopt(argc, argv, "v")) != -1)
|
||||||
|
switch (opt) {
|
||||||
|
case 'v':
|
||||||
|
verbose = 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
usage();
|
||||||
|
}
|
||||||
|
|
||||||
|
argc -= optind;
|
||||||
|
argv += optind;
|
||||||
|
|
||||||
|
/* prepare the test plan */
|
||||||
|
t_prepare(argc, argv);
|
||||||
|
if (t_plan_len == 0)
|
||||||
|
errx(1, "no plan\n");
|
||||||
|
|
||||||
|
/* run the tests */
|
||||||
|
printf("1..%zu\n", t_plan_len);
|
||||||
|
for (n = pass = fail = 0; n < t_plan_len; ++n) {
|
||||||
|
desc = t_plan[n]->desc ? t_plan[n]->desc : "no description";
|
||||||
|
if ((*t_plan[n]->func)(&desc, t_plan[n]->arg)) {
|
||||||
|
printf("ok %d - %s\n", n + 1, desc);
|
||||||
|
++pass;
|
||||||
|
} else {
|
||||||
|
printf("not ok %d - %s\n", n + 1, desc);
|
||||||
|
++fail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* clean up and exit */
|
||||||
|
t_cleanup();
|
||||||
|
exit(fail > 0 ? 1 : 0);
|
||||||
|
}
|
289
t/t_md5.c
Normal file
289
t/t_md5.c
Normal file
|
@ -0,0 +1,289 @@
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2012 Universitetet i Oslo
|
||||||
|
* Copyright (c) 2012-2014 Dag-Erling Smørgrav
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote
|
||||||
|
* products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Dag-Erling Smørgrav <des@des.no>
|
||||||
|
* Sponsor: the University of Oslo
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "cryb/impl.h"
|
||||||
|
|
||||||
|
#include <err.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#include "t.h"
|
||||||
|
|
||||||
|
#if WITH_OPENSSL
|
||||||
|
|
||||||
|
#include <openssl/md5.h>
|
||||||
|
|
||||||
|
#define MD5_DIGEST_LEN MD5_DIGEST_LENGTH
|
||||||
|
|
||||||
|
static void
|
||||||
|
t_md5_complete(const void *msg, size_t msglen, uint8_t *digest)
|
||||||
|
{
|
||||||
|
MD5_CTX ctx;
|
||||||
|
|
||||||
|
MD5_Init(&ctx);
|
||||||
|
MD5_Update(&ctx, msg, msglen);
|
||||||
|
MD5_Final(digest, &ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif WITH_RSAREF
|
||||||
|
|
||||||
|
#include <rsaref.h>
|
||||||
|
|
||||||
|
#define MD5_DIGEST_LEN 16
|
||||||
|
|
||||||
|
static void
|
||||||
|
t_md5_complete(const void *msg, size_t msglen, uint8_t *digest)
|
||||||
|
{
|
||||||
|
MD5_CTX ctx;
|
||||||
|
|
||||||
|
MD5Init(&ctx);
|
||||||
|
MD5Update(&ctx, (unsigned char *)(uintptr_t)msg, msglen);
|
||||||
|
MD5Final(digest, &ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#include <cryb/md5.h>
|
||||||
|
|
||||||
|
#define t_md5_complete(msg, msglen, digest) \
|
||||||
|
md5_complete(msg, msglen, digest)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Test vectors from RFC 1321
|
||||||
|
*/
|
||||||
|
static struct t_vector {
|
||||||
|
const char *msg;
|
||||||
|
const uint8_t digest[MD5_DIGEST_LEN];
|
||||||
|
} t_md5_vectors[] = {
|
||||||
|
{
|
||||||
|
"",
|
||||||
|
{
|
||||||
|
0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04,
|
||||||
|
0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"a",
|
||||||
|
{
|
||||||
|
0x0c, 0xc1, 0x75, 0xb9, 0xc0, 0xf1, 0xb6, 0xa8,
|
||||||
|
0x31, 0xc3, 0x99, 0xe2, 0x69, 0x77, 0x26, 0x61,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"abc",
|
||||||
|
{
|
||||||
|
0x90, 0x01, 0x50, 0x98, 0x3c, 0xd2, 0x4f, 0xb0,
|
||||||
|
0xd6, 0x96, 0x3f, 0x7d, 0x28, 0xe1, 0x7f, 0x72,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"message digest",
|
||||||
|
{
|
||||||
|
0xf9, 0x6b, 0x69, 0x7d, 0x7c, 0xb7, 0x93, 0x8d,
|
||||||
|
0x52, 0x5a, 0x2f, 0x31, 0xaa, 0xf1, 0x61, 0xd0,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"abcdefghijklmnopqrstuvwxyz",
|
||||||
|
{
|
||||||
|
0xc3, 0xfc, 0xd3, 0xd7, 0x61, 0x92, 0xe4, 0x00,
|
||||||
|
0x7d, 0xfb, 0x49, 0x6c, 0xca, 0x67, 0xe1, 0x3b,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||||
|
"abcdefghijklmnopqrstuvwxyz"
|
||||||
|
"0123456789",
|
||||||
|
{
|
||||||
|
0xd1, 0x74, 0xab, 0x98, 0xd2, 0x77, 0xd9, 0xf5,
|
||||||
|
0xa5, 0x61, 0x1c, 0x2c, 0x9f, 0x41, 0x9d, 0x9f,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"1234567890123456789012345678901234567890"
|
||||||
|
"1234567890123456789012345678901234567890",
|
||||||
|
{
|
||||||
|
0x57, 0xed, 0xf4, 0xa2, 0x2b, 0xe3, 0xc9, 0x55,
|
||||||
|
0xac, 0x49, 0xda, 0x2e, 0x21, 0x07, 0xb6, 0x7a,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Unit test: compute the MD5 sum of the specified string and compare it
|
||||||
|
* to the expected result.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
t_md5_vector(char **desc CRYB_UNUSED, void *arg)
|
||||||
|
{
|
||||||
|
struct t_vector *vector = (struct t_vector *)arg;
|
||||||
|
uint8_t digest[MD5_DIGEST_LEN];
|
||||||
|
|
||||||
|
t_md5_complete(vector->msg, strlen(vector->msg), digest);
|
||||||
|
if (memcmp(digest, vector->digest, MD5_DIGEST_LEN) != 0) {
|
||||||
|
t_verbose("expected ");
|
||||||
|
t_verbose_hex(vector->digest, MD5_DIGEST_LEN);
|
||||||
|
t_verbose("\n");
|
||||||
|
t_verbose("got ");
|
||||||
|
t_verbose_hex(digest, MD5_DIGEST_LEN);
|
||||||
|
t_verbose("\n");
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef BENCHMARKS
|
||||||
|
/*
|
||||||
|
* Performance test: measure the time spent computing the MD5 sum of a
|
||||||
|
* message of the specified length.
|
||||||
|
*/
|
||||||
|
#define T_PERF_ITERATIONS 1000
|
||||||
|
static int
|
||||||
|
t_md5_perf(char **desc CRYB_UNUSED, void *arg)
|
||||||
|
{
|
||||||
|
struct timespec ts, te;
|
||||||
|
unsigned long ns;
|
||||||
|
uint8_t digest[MD5_DIGEST_LEN];
|
||||||
|
char *msg, *comment;
|
||||||
|
|
||||||
|
if ((msg = calloc(1, msglen)) == NULL)
|
||||||
|
err(1, "calloc()");
|
||||||
|
clock_gettime(CLOCK_MONOTONIC_PRECISE, &ts);
|
||||||
|
for (int i = 0; i < T_PERF_ITERATIONS; ++i)
|
||||||
|
t_md5_complete(msg, msglen, digest);
|
||||||
|
clock_gettime(CLOCK_MONOTONIC_PRECISE, &te);
|
||||||
|
free(msg);
|
||||||
|
ns = te.tv_sec * 1000000000LU + te.tv_nsec;
|
||||||
|
ns -= ts.tv_sec * 1000000000LU + ts.tv_nsec;
|
||||||
|
asprintf(&comment, "%zu bytes: %d iterations in %'lu ns",
|
||||||
|
msglen, T_PERF_ITERATIONS, ns);
|
||||||
|
if (comment == NULL)
|
||||||
|
err(1, "asprintf()");
|
||||||
|
*desc = (const char *)comment;
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if !defined(WITH_OPENSSL) && !defined(WITH_RSAREF)
|
||||||
|
/*
|
||||||
|
* Various corner cases and error conditions
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
t_md5_short_updates(char **desc CRYB_UNUSED, void *arg)
|
||||||
|
{
|
||||||
|
struct t_vector *vector = (struct t_vector *)arg;
|
||||||
|
uint8_t digest[MD5_DIGEST_LEN];
|
||||||
|
md5_ctx ctx;
|
||||||
|
int i, len;
|
||||||
|
|
||||||
|
md5_init(&ctx);
|
||||||
|
len = strlen(vector->msg);
|
||||||
|
for (i = 0; i + 5 < len; i += 5)
|
||||||
|
md5_update(&ctx, vector->msg + i, 5);
|
||||||
|
md5_update(&ctx, vector->msg + i, len - i);
|
||||||
|
md5_final(&ctx, digest);
|
||||||
|
return (memcmp(digest, vector->digest, MD5_DIGEST_LEN) == 0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef BENCHMARKS
|
||||||
|
/*
|
||||||
|
* Microbenchmarks
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
t_md5_perf_0, "microbenchmark with empty message")
|
||||||
|
{
|
||||||
|
|
||||||
|
return (t_md5_perf(0, desc));
|
||||||
|
}
|
||||||
|
|
||||||
|
T_FUNC(perf_1000, "microbenchmark with 1,000-byte message")
|
||||||
|
{
|
||||||
|
|
||||||
|
return (t_md5_perf(1000, desc));
|
||||||
|
}
|
||||||
|
|
||||||
|
T_FUNC(perf_1000000, "microbenchmark with 1,000,000-byte message")
|
||||||
|
{
|
||||||
|
|
||||||
|
return (t_md5_perf(1000000, desc));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
* Boilerplate
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
t_prepare(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int i, n;
|
||||||
|
|
||||||
|
(void)argc;
|
||||||
|
(void)argv;
|
||||||
|
n = sizeof t_md5_vectors / sizeof t_md5_vectors[0];
|
||||||
|
for (i = 0; i < n; ++i)
|
||||||
|
t_add_test(t_md5_vector, &t_md5_vectors[i],
|
||||||
|
"RFC 1321 test vector %d", i + 1);
|
||||||
|
#if !defined(WITH_OPENSSL) && !defined(WITH_RSAREF)
|
||||||
|
/*
|
||||||
|
* Run test vector 7 (which is 80 characters long) 5 characters at
|
||||||
|
* a time. This tests a) appending data to an underfull block and
|
||||||
|
* b) appending more data to an underfull block than it has room
|
||||||
|
* for (since 64 % 5 != 0). Test vector 7 already exercised the
|
||||||
|
* code path for computing a block directly from source (without
|
||||||
|
* copying it in), and all the test vectors except vector 1
|
||||||
|
* exercised the general case of copying a small amount of data in
|
||||||
|
* without crossing the block boundary.
|
||||||
|
*/
|
||||||
|
t_add_test(t_md5_short_updates, &t_md5_vectors[6],
|
||||||
|
"multiple short updates");
|
||||||
|
// t_add_test(t_md5_partial
|
||||||
|
#endif
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
t_cleanup(void)
|
||||||
|
{
|
||||||
|
}
|
329
t/t_rfc4648.c
Normal file
329
t/t_rfc4648.c
Normal file
|
@ -0,0 +1,329 @@
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2013-2014 Universitetet i Oslo
|
||||||
|
* Copyright (c) 2014 Dag-Erling Smørgrav
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote
|
||||||
|
* products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Dag-Erling Smørgrav <des@des.no>
|
||||||
|
* Sponsor: the University of Oslo
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "cryb/impl.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <cryb/rfc4648.h>
|
||||||
|
|
||||||
|
#include "t.h"
|
||||||
|
|
||||||
|
struct t_case {
|
||||||
|
const char *desc;
|
||||||
|
int (*func)(const char *, size_t, char *, size_t *);
|
||||||
|
const char *in; /* input string */
|
||||||
|
size_t ilen; /* input length */
|
||||||
|
const char *out; /* expected output string or NULL */
|
||||||
|
size_t blen; /* initial value for olen or 0 */
|
||||||
|
size_t olen; /* expected value for olen */
|
||||||
|
int ret; /* expected return value */
|
||||||
|
int err; /* expected errno if ret != 0 */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* basic encoding / decoding */
|
||||||
|
#define T_ENCODE_N(N, i, o) \
|
||||||
|
{ "base"#N"_encode("#i")", b##N##enc, i, sizeof i - 1, \
|
||||||
|
o, sizeof o, sizeof o, 0, 0 }
|
||||||
|
#define T_DECODE_N(N, i, o) \
|
||||||
|
{ "base"#N"_decode("#i")", b##N##dec, i, sizeof i - 1, \
|
||||||
|
o, sizeof o - 1, sizeof o - 1, 0, 0 }
|
||||||
|
#define T_ENCODE(p, b32, b64) \
|
||||||
|
T_ENCODE_N(32, p, b32), T_ENCODE_N(64, p, b64)
|
||||||
|
#define T_DECODE(p, b32, b64) \
|
||||||
|
T_DECODE_N(32, b32, p), T_DECODE_N(64, b64, p)
|
||||||
|
|
||||||
|
/* roundtrip encoding tests */
|
||||||
|
#define T_ENCDEC_N(N, p, e) \
|
||||||
|
T_ENCODE_N(N, p, e), T_DECODE_N(N, e, p)
|
||||||
|
#define T_ENCDEC(p, b32, b64) \
|
||||||
|
T_ENCDEC_N(32, p, b32), T_ENCDEC_N(64, p, b64)
|
||||||
|
|
||||||
|
/* decoding failure */
|
||||||
|
#define T_DECODE_FAIL_N(N, e, i) \
|
||||||
|
{ "base"#N"_decode("#i")", b##N##dec, i, sizeof i - 1, \
|
||||||
|
NULL, 0, 0, -1, e }
|
||||||
|
#define T_DECODE_FAIL(e, b32, b64) \
|
||||||
|
T_DECODE_FAIL_N(32, e, b32), T_DECODE_FAIL_N(64, e, b64)
|
||||||
|
|
||||||
|
/* input string shorter than input length */
|
||||||
|
#define T_SHORT_INPUT_DEC(N, i) \
|
||||||
|
{ "base"#N"_decode (short input)", b##N##dec, i, sizeof i + 2, \
|
||||||
|
NULL, 0, base##N##_declen(sizeof i - 1), 0, 0 }
|
||||||
|
#define T_SHORT_INPUT() \
|
||||||
|
T_SHORT_INPUT_DEC(32, "AAAAAAAA"), \
|
||||||
|
T_SHORT_INPUT_DEC(64, "AAAA")
|
||||||
|
|
||||||
|
/* output string longer than output length */
|
||||||
|
#define T_LONG_OUTPUT_ENC(N, i) \
|
||||||
|
{ "base"#N"_enc (long output)", b##N##enc, i, sizeof i - 1, \
|
||||||
|
NULL, 1, base##N##_enclen(sizeof i - 1) + 1, -1, ENOSPC }
|
||||||
|
#define T_LONG_OUTPUT_DEC(N, i) \
|
||||||
|
{ "base"#N"_decode (long output)", b##N##dec, "AAAAAAAA", 8, \
|
||||||
|
NULL, 1, base##N##_declen(sizeof i - 1), -1, ENOSPC }
|
||||||
|
#define T_LONG_OUTPUT() \
|
||||||
|
T_LONG_OUTPUT_ENC(32, "foo"), \
|
||||||
|
T_LONG_OUTPUT_DEC(32, "AAAAAAAA"), \
|
||||||
|
T_LONG_OUTPUT_ENC(64, "foo"), \
|
||||||
|
T_LONG_OUTPUT_DEC(64, "AAAA")
|
||||||
|
|
||||||
|
static const char b64alphabet[] =
|
||||||
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||||
|
"abcdefghijklmnopqrstuvwxyz"
|
||||||
|
"0123456789+/";
|
||||||
|
static const char b64complete[] = {
|
||||||
|
0x00, 0x10, 0x83, 0x10, 0x51, 0x87,
|
||||||
|
0x20, 0x92, 0x8b, 0x30, 0xd3, 0x8f,
|
||||||
|
0x41, 0x14, 0x93, 0x51, 0x55, 0x97,
|
||||||
|
0x61, 0x96, 0x9b, 0x71, 0xd7, 0x9f,
|
||||||
|
0x82, 0x18, 0xa3, 0x92, 0x59, 0xa7,
|
||||||
|
0xa2, 0x9a, 0xab, 0xb2, 0xdb, 0xaf,
|
||||||
|
0xc3, 0x1c, 0xb3, 0xd3, 0x5d, 0xb7,
|
||||||
|
0xe3, 0x9e, 0xbb, 0xf3, 0xdf, 0xbf,
|
||||||
|
0x00
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char b32alphabet[] =
|
||||||
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
|
||||||
|
static const char b32complete[] = {
|
||||||
|
0x00, 0x44, 0x32, 0x14, 0xc7,
|
||||||
|
0x42, 0x54, 0xb6, 0x35, 0xcf,
|
||||||
|
0x84, 0x65, 0x3a, 0x56, 0xd7,
|
||||||
|
0xc6, 0x75, 0xbe, 0x77, 0xdf,
|
||||||
|
0x00
|
||||||
|
};
|
||||||
|
|
||||||
|
static int
|
||||||
|
b32enc(const char *in, size_t ilen, char *out, size_t *olen)
|
||||||
|
{
|
||||||
|
|
||||||
|
return base32_encode((const uint8_t *)in, ilen, out, olen);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
b32dec(const char *in, size_t ilen, char *out, size_t *olen)
|
||||||
|
{
|
||||||
|
|
||||||
|
return base32_decode(in, ilen, (uint8_t *)out, olen);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
b64enc(const char *in, size_t ilen, char *out, size_t *olen)
|
||||||
|
{
|
||||||
|
|
||||||
|
return base64_encode((const uint8_t *)in, ilen, out, olen);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
b64dec(const char *in, size_t ilen, char *out, size_t *olen)
|
||||||
|
{
|
||||||
|
|
||||||
|
return base64_decode(in, ilen, (uint8_t *)out, olen);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct t_case t_cases[] = {
|
||||||
|
/* complete alphabet */
|
||||||
|
T_ENCDEC_N(32, b32complete, b32alphabet),
|
||||||
|
T_ENCDEC_N(64, b64complete, b64alphabet),
|
||||||
|
|
||||||
|
/* test vectors from RFC 4648 */
|
||||||
|
/* plain base32 base64 */
|
||||||
|
T_ENCDEC("", "", ""),
|
||||||
|
T_ENCDEC("f", "MY======", "Zg=="),
|
||||||
|
T_ENCDEC("fo", "MZXQ====", "Zm8="),
|
||||||
|
T_ENCDEC("foo", "MZXW6===", "Zm9v"),
|
||||||
|
T_ENCDEC("foob", "MZXW6YQ=", "Zm9vYg=="),
|
||||||
|
T_ENCDEC("fooba", "MZXW6YTB", "Zm9vYmE="),
|
||||||
|
T_ENCDEC("foobar", "MZXW6YTBOI======", "Zm9vYmFy"),
|
||||||
|
|
||||||
|
/* zeroes */
|
||||||
|
T_ENCDEC("\0\0\0", "AAAAA===", "AAAA"),
|
||||||
|
|
||||||
|
/* sloppy padding */
|
||||||
|
T_DECODE("f", "MY=", "Zg="),
|
||||||
|
T_DECODE("f", "MY", "Zg"),
|
||||||
|
|
||||||
|
/* whitespace */
|
||||||
|
/* plain base32 base64 */
|
||||||
|
T_DECODE("tst", "ORZX I===", "dH N0"),
|
||||||
|
T_DECODE("tst", "ORZX\tI===", "dH\tN0"),
|
||||||
|
T_DECODE("tst", "ORZX\rI===", "dH\rN0"),
|
||||||
|
T_DECODE("tst", "ORZX\nI===", "dH\nN0"),
|
||||||
|
|
||||||
|
/* invalid character in data */
|
||||||
|
T_DECODE_FAIL(EINVAL, "AA!AAAAAA", "AA!A"),
|
||||||
|
|
||||||
|
/* invalid character in padding */
|
||||||
|
T_DECODE_FAIL(EINVAL, "AAAAA==!", "AA=!"),
|
||||||
|
|
||||||
|
/* padding with no data */
|
||||||
|
T_DECODE_FAIL(EINVAL, "AAAAAAAA=", "AAAA="),
|
||||||
|
|
||||||
|
/* data after padding */
|
||||||
|
T_DECODE_FAIL(EINVAL, "AA=A", "AA=A"),
|
||||||
|
|
||||||
|
/* padding in the wrong place, or non-zero bits in padding */
|
||||||
|
T_DECODE_FAIL_N(32, EINVAL, "A======="),
|
||||||
|
T_DECODE_N (32, "AA======", "\x00"),
|
||||||
|
T_DECODE_FAIL_N(32, EINVAL, "AB======"),
|
||||||
|
T_DECODE_FAIL_N(32, EINVAL, "AC======"),
|
||||||
|
T_DECODE_FAIL_N(32, EINVAL, "AD======"),
|
||||||
|
T_DECODE_N (32, "AE======", "\x01"),
|
||||||
|
T_DECODE_FAIL_N(32, EINVAL, "AAA====="),
|
||||||
|
T_DECODE_N (32, "AAAA====", "\x00\x00"),
|
||||||
|
T_DECODE_FAIL_N(32, EINVAL, "AAAB===="),
|
||||||
|
T_DECODE_FAIL_N(32, EINVAL, "AAAC===="),
|
||||||
|
T_DECODE_FAIL_N(32, EINVAL, "AAAD===="),
|
||||||
|
T_DECODE_FAIL_N(32, EINVAL, "AAAE===="),
|
||||||
|
T_DECODE_FAIL_N(32, EINVAL, "AAAF===="),
|
||||||
|
T_DECODE_FAIL_N(32, EINVAL, "AAAG===="),
|
||||||
|
T_DECODE_FAIL_N(32, EINVAL, "AAAH===="),
|
||||||
|
T_DECODE_FAIL_N(32, EINVAL, "AAAI===="),
|
||||||
|
T_DECODE_FAIL_N(32, EINVAL, "AAAJ===="),
|
||||||
|
T_DECODE_FAIL_N(32, EINVAL, "AAAK===="),
|
||||||
|
T_DECODE_FAIL_N(32, EINVAL, "AAAL===="),
|
||||||
|
T_DECODE_FAIL_N(32, EINVAL, "AAAM===="),
|
||||||
|
T_DECODE_FAIL_N(32, EINVAL, "AAAN===="),
|
||||||
|
T_DECODE_FAIL_N(32, EINVAL, "AAAO===="),
|
||||||
|
T_DECODE_FAIL_N(32, EINVAL, "AAAP===="),
|
||||||
|
T_DECODE_N (32, "AAAQ====", "\x00\x01"),
|
||||||
|
T_DECODE_N (32, "AAAAA===", "\x00\x00\x00"),
|
||||||
|
T_DECODE_FAIL_N(32, EINVAL, "AAAAB==="),
|
||||||
|
T_DECODE_N (32, "AAAAC===", "\x00\x00\x01"),
|
||||||
|
T_DECODE_FAIL_N(32, EINVAL, "AAAAAA=="),
|
||||||
|
T_DECODE_N (32, "AAAAAAA=", "\x00\x00\x00\x00"),
|
||||||
|
T_DECODE_FAIL_N(32, EINVAL, "AAAAAAB="),
|
||||||
|
T_DECODE_FAIL_N(32, EINVAL, "AAAAAAC="),
|
||||||
|
T_DECODE_FAIL_N(32, EINVAL, "AAAAAAD="),
|
||||||
|
T_DECODE_FAIL_N(32, EINVAL, "AAAAAAE="),
|
||||||
|
T_DECODE_FAIL_N(32, EINVAL, "AAAAAAF="),
|
||||||
|
T_DECODE_FAIL_N(32, EINVAL, "AAAAAAG="),
|
||||||
|
T_DECODE_FAIL_N(32, EINVAL, "AAAAAAH="),
|
||||||
|
T_DECODE_N (32, "AAAAAAI=", "\x00\x00\x00\x01"),
|
||||||
|
T_DECODE_N (32, "AAAAAAAA", "\x00\x00\x00\x00\x00"),
|
||||||
|
|
||||||
|
T_DECODE_FAIL_N(64, EINVAL, "A==="),
|
||||||
|
T_DECODE_N (64, "AA==", "\x00"),
|
||||||
|
T_DECODE_FAIL_N(64, EINVAL, "AB=="),
|
||||||
|
T_DECODE_FAIL_N(64, EINVAL, "AC=="),
|
||||||
|
T_DECODE_FAIL_N(64, EINVAL, "AD=="),
|
||||||
|
T_DECODE_FAIL_N(64, EINVAL, "AE=="),
|
||||||
|
T_DECODE_FAIL_N(64, EINVAL, "AF=="),
|
||||||
|
T_DECODE_FAIL_N(64, EINVAL, "AG=="),
|
||||||
|
T_DECODE_FAIL_N(64, EINVAL, "AH=="),
|
||||||
|
T_DECODE_FAIL_N(64, EINVAL, "AI=="),
|
||||||
|
T_DECODE_FAIL_N(64, EINVAL, "AJ=="),
|
||||||
|
T_DECODE_FAIL_N(64, EINVAL, "AK=="),
|
||||||
|
T_DECODE_FAIL_N(64, EINVAL, "AL=="),
|
||||||
|
T_DECODE_FAIL_N(64, EINVAL, "AM=="),
|
||||||
|
T_DECODE_FAIL_N(64, EINVAL, "AN=="),
|
||||||
|
T_DECODE_FAIL_N(64, EINVAL, "AO=="),
|
||||||
|
T_DECODE_FAIL_N(64, EINVAL, "AP=="),
|
||||||
|
T_DECODE_N (64, "AQ==", "\x01"),
|
||||||
|
T_DECODE_N (64, "AAA=", "\x00\x00"),
|
||||||
|
T_DECODE_FAIL_N(64, EINVAL, "AAB="),
|
||||||
|
T_DECODE_FAIL_N(64, EINVAL, "AAC="),
|
||||||
|
T_DECODE_FAIL_N(64, EINVAL, "AAD="),
|
||||||
|
T_DECODE_N (64, "AAE=", "\x00\x01"),
|
||||||
|
|
||||||
|
/* various error conditions */
|
||||||
|
T_SHORT_INPUT(),
|
||||||
|
T_LONG_OUTPUT(),
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Encoding test function
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
t_rfc4648(char **desc CRYB_UNUSED, void *arg)
|
||||||
|
{
|
||||||
|
struct t_case *t = arg;
|
||||||
|
char buf[256];
|
||||||
|
size_t len;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
len = t->blen ? t->blen : sizeof buf;
|
||||||
|
ret = t->func(t->in, t->ilen, buf, &len);
|
||||||
|
if (ret != t->ret) {
|
||||||
|
t_verbose("expected return code %d, got %d\n",
|
||||||
|
t->ret, ret);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
if (t->out && len != t->olen) {
|
||||||
|
t_verbose("expected output length %zu, got %zu\n",
|
||||||
|
t->olen, len);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
if (t->ret != 0 && errno != t->err) {
|
||||||
|
t_verbose("expected errno %d, got %d\n",
|
||||||
|
t->err, errno);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
if (t->ret == 0 && t->out && strncmp(buf, t->out, len) != 0) {
|
||||||
|
t_verbose("expected '%.*s' got '%.*s'\n",
|
||||||
|
(int)t->olen, t->out, (int)len, buf);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Generate the test plan
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
t_prepare(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int i, n;
|
||||||
|
|
||||||
|
(void)argc;
|
||||||
|
(void)argv;
|
||||||
|
n = sizeof t_cases / sizeof t_cases[0];
|
||||||
|
for (i = 0; i < n; ++i)
|
||||||
|
t_add_test(t_rfc4648, &t_cases[i], t_cases[i].desc);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Cleanup
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
t_cleanup(void)
|
||||||
|
{
|
||||||
|
}
|
284
t/t_sha1.c
Normal file
284
t/t_sha1.c
Normal file
|
@ -0,0 +1,284 @@
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2012 Universitetet i Oslo
|
||||||
|
* Copyright (c) 2012-2014 Dag-Erling Smørgrav
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote
|
||||||
|
* products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Author: Dag-Erling Smørgrav <des@des.no>
|
||||||
|
* Sponsor: the University of Oslo
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "cryb/impl.h"
|
||||||
|
|
||||||
|
#include <err.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#include "t.h"
|
||||||
|
|
||||||
|
#if WITH_OPENSSL
|
||||||
|
|
||||||
|
#include <openssl/sha.h>
|
||||||
|
|
||||||
|
#define SHA1_DIGEST_LEN SHA_DIGEST_LENGTH
|
||||||
|
|
||||||
|
static void
|
||||||
|
t_sha1_complete(const void *msg, size_t msglen, uint8_t *digest)
|
||||||
|
{
|
||||||
|
SHA_CTX ctx;
|
||||||
|
|
||||||
|
SHA1_Init(&ctx);
|
||||||
|
SHA1_Update(&ctx, msg, msglen);
|
||||||
|
SHA1_Final(digest, &ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#include <cryb/sha1.h>
|
||||||
|
|
||||||
|
#define t_sha1_complete(msg, msglen, digest) \
|
||||||
|
sha1_complete(msg, msglen, digest)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static struct t_vector {
|
||||||
|
const char *desc;
|
||||||
|
const char *msg;
|
||||||
|
const uint8_t digest[SHA1_DIGEST_LEN];
|
||||||
|
} t_sha1_vectors[] = {
|
||||||
|
{
|
||||||
|
"zero-length message",
|
||||||
|
"",
|
||||||
|
{
|
||||||
|
0xda, 0x39, 0xa3, 0xee, 0x5e, 0x6b, 0x4b, 0x0d,
|
||||||
|
0x32, 0x55, 0xbf, 0xef, 0x95, 0x60, 0x18, 0x90,
|
||||||
|
0xaf, 0xd8, 0x07, 0x09,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"FIPS 180-2 A.1 (one-block message)",
|
||||||
|
"abc",
|
||||||
|
{
|
||||||
|
0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81, 0x6a,
|
||||||
|
0xba, 0x3e, 0x25, 0x71, 0x78, 0x50, 0xc2, 0x6c,
|
||||||
|
0x9c, 0xd0, 0xd8, 0x9d,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* This message is *just* long enough to necessitate a
|
||||||
|
* second block, which consists entirely of padding.
|
||||||
|
*/
|
||||||
|
"FIPS 180-2 A.2 (multi-block message)",
|
||||||
|
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
|
||||||
|
{
|
||||||
|
0x84, 0x98, 0x3e, 0x44, 0x1c, 0x3b, 0xd2, 0x6e,
|
||||||
|
0xba, 0xae, 0x4a, 0xa1, 0xf9, 0x51, 0x29, 0xe5,
|
||||||
|
0xe5, 0x46, 0x70, 0xf1,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* 1,000,000 x 'a', filled in by t_prepare()
|
||||||
|
*/
|
||||||
|
"FIPS 180-2 A.3 (long message)",
|
||||||
|
NULL,
|
||||||
|
{
|
||||||
|
0x34, 0xaa, 0x97, 0x3c, 0xd4, 0xc4, 0xda, 0xa4,
|
||||||
|
0xf6, 0x1e, 0xeb, 0x2b, 0xdb, 0xad, 0x27, 0x31,
|
||||||
|
0x65, 0x34, 0x01, 0x6f,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* One of the MD5 test vectors, included for the "short
|
||||||
|
* update" test.
|
||||||
|
*/
|
||||||
|
"\"1234567890\"x8",
|
||||||
|
"1234567890123456789012345678901234567890"
|
||||||
|
"1234567890123456789012345678901234567890",
|
||||||
|
{
|
||||||
|
0x50, 0xab, 0xf5, 0x70, 0x6a, 0x15, 0x09, 0x90,
|
||||||
|
0xa0, 0x8b, 0x2c, 0x5e, 0xa4, 0x0f, 0xa0, 0xe5,
|
||||||
|
0x85, 0x55, 0x47, 0x32,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Unit test: compute the SHA1 sum of the specified string and compare it
|
||||||
|
* to the expected result.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
t_sha1_vector(char **desc CRYB_UNUSED, void *arg)
|
||||||
|
{
|
||||||
|
struct t_vector *vector = (struct t_vector *)arg;
|
||||||
|
uint8_t digest[SHA1_DIGEST_LEN];
|
||||||
|
char *msg;
|
||||||
|
|
||||||
|
if (vector->msg) {
|
||||||
|
t_sha1_complete(vector->msg, strlen(vector->msg), digest);
|
||||||
|
} else {
|
||||||
|
/* special case for FIPS test vector 3 */
|
||||||
|
if ((msg = malloc(1000000)) == NULL)
|
||||||
|
err(1, "malloc()");
|
||||||
|
memset(msg, 'a', 1000000);
|
||||||
|
t_sha1_complete(msg, 1000000, digest);
|
||||||
|
free(msg);
|
||||||
|
}
|
||||||
|
if (memcmp(digest, vector->digest, SHA1_DIGEST_LEN) != 0) {
|
||||||
|
t_verbose("expected ");
|
||||||
|
t_verbose_hex(vector->digest, SHA1_DIGEST_LEN);
|
||||||
|
t_verbose("\n");
|
||||||
|
t_verbose("got ");
|
||||||
|
t_verbose_hex(digest, SHA1_DIGEST_LEN);
|
||||||
|
t_verbose("\n");
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if !defined(WITH_OPENSSL) && !defined(WITH_RSAREF)
|
||||||
|
/*
|
||||||
|
* Various corner cases and error conditions
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
t_sha1_short_updates(char **desc CRYB_UNUSED, void *arg)
|
||||||
|
{
|
||||||
|
struct t_vector *vector = (struct t_vector *)arg;
|
||||||
|
uint8_t digest[SHA1_DIGEST_LEN];
|
||||||
|
sha1_ctx ctx;
|
||||||
|
int i, len;
|
||||||
|
|
||||||
|
sha1_init(&ctx);
|
||||||
|
len = strlen(vector->msg);
|
||||||
|
for (i = 0; i + 5 < len; i += 5)
|
||||||
|
sha1_update(&ctx, vector->msg + i, 5);
|
||||||
|
sha1_update(&ctx, vector->msg + i, len - i);
|
||||||
|
sha1_final(&ctx, digest);
|
||||||
|
return (memcmp(digest, vector->digest, SHA1_DIGEST_LEN) == 0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef BENCHMARKS
|
||||||
|
/*
|
||||||
|
* Performance test: measure the time spent computing the SHA1 sum of a
|
||||||
|
* message of the specified length.
|
||||||
|
*/
|
||||||
|
#define T_PERF_ITERATIONS 1000
|
||||||
|
static int
|
||||||
|
t_sha1_perf(const char **desc, void *arg)
|
||||||
|
{
|
||||||
|
struct timespec ts, te;
|
||||||
|
unsigned long ns;
|
||||||
|
uint8_t digest[SHA1_DIGEST_LEN];
|
||||||
|
char *msg, *comment;
|
||||||
|
|
||||||
|
if ((msg = calloc(1, msglen)) == NULL)
|
||||||
|
err(1, "calloc()");
|
||||||
|
clock_gettime(CLOCK_MONOTONIC_PRECISE, &ts);
|
||||||
|
for (int i = 0; i < T_PERF_ITERATIONS; ++i)
|
||||||
|
t_sha1_complete(msg, msglen, digest);
|
||||||
|
clock_gettime(CLOCK_MONOTONIC_PRECISE, &te);
|
||||||
|
free(msg);
|
||||||
|
ns = te.tv_sec * 1000000000LU + te.tv_nsec;
|
||||||
|
ns -= ts.tv_sec * 1000000000LU + ts.tv_nsec;
|
||||||
|
asprintf(&comment, "%zu bytes: %d iterations in %'lu ns",
|
||||||
|
msglen, T_PERF_ITERATIONS, ns);
|
||||||
|
if (comment == NULL)
|
||||||
|
err(1, "asprintf()");
|
||||||
|
*desc = (const char *)comment;
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef BENCHMARKS
|
||||||
|
/*
|
||||||
|
* Microbenchmarks
|
||||||
|
*/
|
||||||
|
T_FUNC(perf_0, "microbenchmark with empty message")
|
||||||
|
{
|
||||||
|
|
||||||
|
return (t_sha1_perf(0, desc));
|
||||||
|
}
|
||||||
|
|
||||||
|
T_FUNC(perf_1000, "microbenchmark with 1,000-byte message")
|
||||||
|
{
|
||||||
|
|
||||||
|
return (t_sha1_perf(1000, desc));
|
||||||
|
}
|
||||||
|
|
||||||
|
T_FUNC(perf_1000000, "microbenchmark with 1,000,000-byte message")
|
||||||
|
{
|
||||||
|
|
||||||
|
return (t_sha1_perf(1000000, desc));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
* Boilerplate
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
t_prepare(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int i, n;
|
||||||
|
|
||||||
|
(void)argc;
|
||||||
|
(void)argv;
|
||||||
|
n = sizeof t_sha1_vectors / sizeof t_sha1_vectors[0];
|
||||||
|
for (i = 0; i < n; ++i)
|
||||||
|
t_add_test(t_sha1_vector, &t_sha1_vectors[i],
|
||||||
|
t_sha1_vectors[i].desc);
|
||||||
|
#if !defined(WITH_OPENSSL) && !defined(WITH_RSAREF)
|
||||||
|
/*
|
||||||
|
* Run test vector 5 (md5 test vector 7, which is 80 characters
|
||||||
|
* long) 5 characters at a time. This tests a) appending data to
|
||||||
|
* an underfull block and b) appending more data to an underfull
|
||||||
|
* block than it has room for (since 64 % 5 != 0). Test vector 4
|
||||||
|
* and 5 already exercised the code path for computing a block
|
||||||
|
* directly from source (without copying it in), and all the test
|
||||||
|
* vectors except vector 1 exercised the general case of copying a
|
||||||
|
* small amount of data in without crossing the block boundary.
|
||||||
|
*/
|
||||||
|
t_add_test(t_sha1_short_updates, &t_sha1_vectors[4],
|
||||||
|
"multiple short updates");
|
||||||
|
#endif
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
t_cleanup(void)
|
||||||
|
{
|
||||||
|
}
|
21
tools/setprops.sh
Executable file
21
tools/setprops.sh
Executable file
|
@ -0,0 +1,21 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
istext() {
|
||||||
|
local mimetype=$(svn propget svn:mime-type "$1" 2>/dev/null)
|
||||||
|
[ -z "$mimetype" ] || expr "$mimetype" : '^text/.' >/dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
(svn list -R ; svn stat | awk '$1 == "A" { print $2 }') | sort -u |
|
||||||
|
while read f ; do
|
||||||
|
[ -f "$f" ] || continue
|
||||||
|
istext "$f" || continue
|
||||||
|
case $f in
|
||||||
|
*.sh|*.pl)
|
||||||
|
svn propset svn:executable \* $f
|
||||||
|
;&
|
||||||
|
*)
|
||||||
|
svn propset eol-style native $f
|
||||||
|
svn propset svn:keywords Id $f
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
Loading…
Reference in a new issue